forked from CredenceOrg/Credence-Frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgress.tsx
More file actions
102 lines (97 loc) · 2.88 KB
/
Copy pathProgress.tsx
File metadata and controls
102 lines (97 loc) · 2.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import './Progress.css'
export interface ProgressProps {
/**
* Current value of the progress indicator.
* For determinate mode, provide a number between `min` and `max`.
* Omit (or pass `undefined`) for indeterminate mode.
*/
value?: number
/** Minimum value for determinate mode. Defaults to 0. */
min?: number
/** Maximum value for determinate mode. Defaults to 100. */
max?: number
/**
* Accessible label announcing what is loading.
* Required: every progress bar must have an accessible name.
*/
'aria-label': string
/** Additional class names appended to the root element. */
className?: string
/** Size variant affecting bar height. Defaults to `'md'`. */
size?: 'sm' | 'md' | 'lg'
/**
* Adds diagonal stripes to the fill bar for visual distinction.
* Works in both determinate and indeterminate modes.
*/
striped?: boolean
/**
* Animates the striped pattern so it scrolls across the bar.
* Implies `striped` when set to `true`.
* Respects `prefers-reduced-motion: reduce`.
*/
animated?: boolean
}
/**
* Accessible progress bar component.
*
* Renders a `role="progressbar"` element. When `value` is provided the bar is
* **determinate** and `aria-valuenow`, `aria-valuemin`, and `aria-valuemax`
* reflect the current fill percentage. When `value` is omitted the bar is
* **indeterminate** and none of the `aria-value*` attributes are set, signalling
* to assistive technology that the completion amount is unknown.
*/
export default function Progress({
value,
min = 0,
max = 100,
'aria-label': ariaLabel,
className = '',
size = 'md',
striped = false,
animated = false,
}: ProgressProps) {
const isIndeterminate = value === undefined
const showStripes = striped || animated
const clampedValue = isIndeterminate ? undefined : Math.min(Math.max(value, min), max)
const percentage = isIndeterminate
? undefined
: max === min
? 0
: ((clampedValue! - min) / (max - min)) * 100
const rootClass = [
'progress',
`progress--${size}`,
isIndeterminate ? 'progress--indeterminate' : 'progress--determinate',
showStripes ? 'progress--striped' : '',
animated ? 'progress--animated' : '',
className,
]
.filter(Boolean)
.join(' ')
return (
<div
role="progressbar"
aria-label={ariaLabel}
aria-valuenow={clampedValue}
aria-valuemin={isIndeterminate ? undefined : min}
aria-valuemax={isIndeterminate ? undefined : max}
className={rootClass}
>
<div
className="progress__track"
aria-hidden="true"
>
<div
className="progress__fill"
style={
isIndeterminate
? undefined
: ({ '--progress-fill': `${percentage}%` } as React.CSSProperties & {
'--progress-fill': string
})
}
/>
</div>
</div>
)
}