From d5c43662a7848cac44e1771d3c33a08a2de4d715 Mon Sep 17 00:00:00 2001
From: Giuseppe Ciotola <30926550+gciotola@users.noreply.github.com>
Date: Mon, 11 Nov 2024 16:36:30 +0100
Subject: [PATCH] fix: add `displayMode` to Progress to display percentage
details
---
.../src/ui/atoms/Progress.test.tsx | 28 +++++++++++++++
.../app-elements/src/ui/atoms/Progress.tsx | 34 +++++++++++++++----
.../src/stories/atoms/Progress.stories.tsx | 20 +++++++++++
3 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/packages/app-elements/src/ui/atoms/Progress.test.tsx b/packages/app-elements/src/ui/atoms/Progress.test.tsx
index 3a9c3f3e0..1b3628f14 100644
--- a/packages/app-elements/src/ui/atoms/Progress.test.tsx
+++ b/packages/app-elements/src/ui/atoms/Progress.test.tsx
@@ -26,4 +26,32 @@ describe('Progress', () => {
''
)
})
+
+ test('Should display the completion status as fraction by default', () => {
+ const { getByText } = render(
+
+ )
+ expect(getByText('12/20')).toBeVisible()
+ })
+
+ test('Should display the completion status as percentage', () => {
+ const { getByText } = render(
+
+ )
+ expect(getByText('60%')).toBeVisible()
+ })
+
+ test('Should render hidden text `max/max` to keep right space and alignments', () => {
+ const { getByText } = render(
+
+ )
+ expect(getByText('1/20')).toBeVisible()
+ expect(getByText('20/20')).toHaveClass('invisible')
+ })
})
diff --git a/packages/app-elements/src/ui/atoms/Progress.tsx b/packages/app-elements/src/ui/atoms/Progress.tsx
index 2ee546df1..f93034cb0 100644
--- a/packages/app-elements/src/ui/atoms/Progress.tsx
+++ b/packages/app-elements/src/ui/atoms/Progress.tsx
@@ -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
}
@@ -30,6 +36,7 @@ export const Progress: React.FC = ({
value,
children,
className,
+ displayMode = 'fraction',
...rest
}) => {
return (
@@ -45,12 +52,25 @@ export const Progress: React.FC = ({
{value != null && (
-
- {value}/{max}
-
-
- {max}/{max}
-
+ {displayMode === 'fraction' ? (
+ <>
+
+ {value}/{max}
+
+
+ {max}/{max}
+
+ >
+ ) : displayMode === 'percentage' ? (
+ <>
+
+ {Math.round((value / max) * 100)}%
+
+
+ 100%
+
+ >
+ ) : null}
)}
diff --git a/packages/docs/src/stories/atoms/Progress.stories.tsx b/packages/docs/src/stories/atoms/Progress.stories.tsx
index 4d99131e7..cde3f21b9 100644
--- a/packages/docs/src/stories/atoms/Progress.stories.tsx
+++ b/packages/docs/src/stories/atoms/Progress.stories.tsx
@@ -23,3 +23,23 @@ export const Indeterminate: StoryFn = (args) => (
)
Indeterminate.args = {}
+
+/** Display completion percentage using `displayMode` prop */
+export const WithPercentage: StoryFn = (args) => (
+
+)
+WithPercentage.args = {
+ max: 100,
+ value: 40,
+ displayMode: 'percentage'
+}
+
+/** Only show the progress bar, without completion details */
+export const OnlyBar: StoryFn = (args) => (
+
+)
+OnlyBar.args = {
+ max: 100,
+ value: 40,
+ displayMode: 'none'
+}