Skip to content

Commit

Permalink
Add animated prop to ProgressBar (#4061)
Browse files Browse the repository at this point in the history
* adds animated prop to ProgressBar

* updates component docs

* adds changeset
  • Loading branch information
mperrotti authored Dec 20, 2023
1 parent c2a53a0 commit f46c071
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 3 deletions.
7 changes: 7 additions & 0 deletions .changeset/serious-drinks-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@primer/react': minor
---

Adds a new prop, `animated`, to the ProgressBar component. This allows the "filled" segment(s) to animate and indicate some process is still in progress.

<!-- Changed components: ProgressBar -->
5 changes: 5 additions & 0 deletions src/ProgressBar/ProgressBar.docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
"a11yReviewed": false,
"stories": [],
"props": [
{
"name": "animated",
"type": "boolean",
"description": "Whether the filled in area(s) of the progress bar will be animated or not"
},
{
"name": "progress",
"type": "number",
Expand Down
2 changes: 2 additions & 0 deletions src/ProgressBar/ProgressBar.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ export const MultipleItems = () => (
<ProgressBar.Item progress={14} sx={{backgroundColor: 'severe.emphasis'}} />
</ProgressBar>
)

export const Animated = () => <ProgressBar progress="50" aria-label="Upload test.png" animated />
26 changes: 23 additions & 3 deletions src/ProgressBar/ProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
import React, {forwardRef} from 'react'
import styled from 'styled-components'
import styled, {keyframes} from 'styled-components'
import {width, WidthProps} from 'styled-system'
import {get} from '../constants'
import sx, {SxProp} from '../sx'
import {warning} from '../utils/warning'

type ProgressProp = {progress?: string | number}

const shimmer = keyframes`
from { mask-position: 200%; }
to { mask-position: 0%; }
`

export const Item = styled.span<ProgressProp & SxProp>`
width: ${props => (props.progress ? `${props.progress}%` : 0)};
background-color: ${get('colors.success.emphasis')};
@media (prefers-reduced-motion: no-preference) {
&[data-animated='true'] {
mask-image: linear-gradient(75deg, #000 30%, rgba(0, 0, 0, 0.65) 80%);
mask-size: 200%;
animation: ${shimmer};
animation-duration: 1s;
animation-iteration-count: infinite;
}
}
${sx};
`

Expand All @@ -24,6 +40,7 @@ const sizeMap = {
type StyledProgressContainerProps = {
inline?: boolean
barSize?: keyof typeof sizeMap
animated?: boolean
} & WidthProps &
SxProp

Expand All @@ -42,7 +59,10 @@ export type ProgressBarProps = React.HTMLAttributes<HTMLSpanElement> & {bg?: str
ProgressProp

export const ProgressBar = forwardRef<HTMLSpanElement, ProgressBarProps>(
({progress, bg = 'success.emphasis', barSize = 'default', children, ...rest}: ProgressBarProps, forwardRef) => {
(
{animated, progress, bg = 'success.emphasis', barSize = 'default', children, ...rest}: ProgressBarProps,
forwardRef,
) => {
if (children && progress) {
throw new Error('You should pass `progress` or children, not both.')
}
Expand All @@ -65,7 +85,7 @@ export const ProgressBar = forwardRef<HTMLSpanElement, ProgressBarProps>(

return (
<ProgressContainer ref={forwardRef} role="progressbar" barSize={barSize} {...ariaAttributes} {...rest}>
{children ?? <Item progress={progress} sx={{backgroundColor: bg}} />}
{children ?? <Item data-animated={animated} progress={progress} sx={{backgroundColor: bg}} />}
</ProgressContainer>
)
},
Expand Down
30 changes: 30 additions & 0 deletions src/__tests__/__snapshots__/ProgressBar.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ exports[`ProgressBar renders consistently 1`] = `
height: 8px;
}
@media (prefers-reduced-motion:no-preference) {
.c1[data-animated='true'] {
-webkit-mask-image: linear-gradient(75deg,#000 30%,rgba(0,0,0,0.65) 80%);
mask-image: linear-gradient(75deg,#000 30%,rgba(0,0,0,0.65) 80%);
-webkit-mask-size: 200%;
mask-size: 200%;
-webkit-animation: jiNfbM;
animation: jiNfbM;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
}
<span
aria-busy={false}
aria-valuemax={100}
Expand Down Expand Up @@ -49,6 +64,21 @@ exports[`ProgressBar respects the "progress" prop 1`] = `
height: 8px;
}
@media (prefers-reduced-motion:no-preference) {
.c1[data-animated='true'] {
-webkit-mask-image: linear-gradient(75deg,#000 30%,rgba(0,0,0,0.65) 80%);
mask-image: linear-gradient(75deg,#000 30%,rgba(0,0,0,0.65) 80%);
-webkit-mask-size: 200%;
mask-size: 200%;
-webkit-animation: jiNfbM;
animation: jiNfbM;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
}
<span
aria-busy={true}
aria-label="Upload test.png"
Expand Down

0 comments on commit f46c071

Please sign in to comment.