Skip to content

Commit

Permalink
fix: add displayMode to Progress to display percentage details
Browse files Browse the repository at this point in the history
  • Loading branch information
gciotola committed Nov 11, 2024
1 parent 6e604b0 commit d5c4366
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 7 deletions.
28 changes: 28 additions & 0 deletions packages/app-elements/src/ui/atoms/Progress.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,32 @@ describe('Progress', () => {
'<progress class="progress" max="20" value="12">20%</progress>'
)
})

test('Should display the completion status as fraction by default', () => {
const { getByText } = render(
<Progress max={20} value={12}>
sample label
</Progress>
)
expect(getByText('12/20')).toBeVisible()
})

test('Should display the completion status as percentage', () => {
const { getByText } = render(
<Progress max={20} value={12} displayMode='percentage'>
sample label
</Progress>
)
expect(getByText('60%')).toBeVisible()
})

test('Should render hidden text `max/max` to keep right space and alignments', () => {
const { getByText } = render(
<Progress max={20} value={1} displayMode='fraction'>
sample label
</Progress>
)
expect(getByText('1/20')).toBeVisible()
expect(getByText('20/20')).toHaveClass('invisible')
})
})
34 changes: 27 additions & 7 deletions packages/app-elements/src/ui/atoms/Progress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ export interface ProgressProps
* this indicates that an activity is ongoing with no indication of how long it is expected to take.
*/
value?: number

/**
* The display mode of the progress bar.
* - `fraction` - Display the completion status as a fraction (default)
* - `percentage` - Display the completion status as a percentage
* - `none` - Do not display the completion
*/
displayMode?: 'fraction' | 'percentage' | 'none'
children: React.ReactNode
}

Expand All @@ -30,6 +36,7 @@ export const Progress: React.FC<ProgressProps> = ({
value,
children,
className,
displayMode = 'fraction',
...rest
}) => {
return (
Expand All @@ -45,12 +52,25 @@ export const Progress: React.FC<ProgressProps> = ({

{value != null && (
<span className='flex-nowrap text-gray-400 text-xs font-extrabold relative'>
<span className='absolute right-0'>
{value}/{max}
</span>
<span className='invisible' aria-hidden='true'>
{max}/{max}
</span>
{displayMode === 'fraction' ? (
<>
<span className='absolute right-0'>
{value}/{max}
</span>
<span className='invisible' aria-hidden='true'>
{max}/{max}
</span>
</>
) : displayMode === 'percentage' ? (
<>
<span className='absolute right-0'>
{Math.round((value / max) * 100)}%
</span>
<span className='invisible' aria-hidden='true'>
100%
</span>
</>
) : null}
</span>
)}
</div>
Expand Down
20 changes: 20 additions & 0 deletions packages/docs/src/stories/atoms/Progress.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,23 @@ export const Indeterminate: StoryFn<typeof Progress> = (args) => (
<Progress {...args}>Loading...</Progress>
)
Indeterminate.args = {}

/** Display completion percentage using `displayMode` prop */
export const WithPercentage: StoryFn<typeof Progress> = (args) => (
<Progress {...args}>40%</Progress>
)
WithPercentage.args = {
max: 100,
value: 40,
displayMode: 'percentage'
}

/** Only show the progress bar, without completion details */
export const OnlyBar: StoryFn<typeof Progress> = (args) => (
<Progress {...args}>40%</Progress>
)
OnlyBar.args = {
max: 100,
value: 40,
displayMode: 'none'
}

0 comments on commit d5c4366

Please sign in to comment.