@@ -5,7 +5,6 @@ import {width} from 'styled-system'
5
5
import { get } from '../constants'
6
6
import type { SxProp } from '../sx'
7
7
import sx from '../sx'
8
- import { warning } from '../utils/warning'
9
8
10
9
type ProgressProp = {
11
10
progress ?: string | number
@@ -17,7 +16,7 @@ const shimmer = keyframes`
17
16
to { mask-position: 0%; }
18
17
`
19
18
20
- export const Item = styled . span < ProgressProp & SxProp > `
19
+ const ProgressItem = styled . span < ProgressProp & SxProp > `
21
20
width: ${ props => ( props . progress ? `${ props . progress } %` : 0 ) } ;
22
21
background-color: ${ props => get ( `colors.${ props . bg || 'success.emphasis' } ` ) } ;
23
22
@@ -34,8 +33,6 @@ export const Item = styled.span<ProgressProp & SxProp>`
34
33
${ sx } ;
35
34
`
36
35
37
- Item . displayName = 'ProgressBar.Item'
38
-
39
36
const sizeMap = {
40
37
small : '5px' ,
41
38
large : '10px' ,
@@ -60,37 +57,78 @@ const ProgressContainer = styled.span<StyledProgressContainerProps>`
60
57
${ sx } ;
61
58
`
62
59
60
+ export type ProgressBarItems = React . HTMLAttributes < HTMLSpanElement > & { 'aria-label' ?: string } & ProgressProp & SxProp
61
+
62
+ export const Item = forwardRef < HTMLSpanElement , ProgressBarItems > (
63
+ (
64
+ { progress, 'aria-label' : ariaLabel , 'aria-valuenow' : ariaValueNow , 'aria-valuetext' : ariaValueText , ...rest } ,
65
+ forwardRef ,
66
+ ) => {
67
+ const progressAsNumber = typeof progress === 'string' ? parseInt ( progress , 10 ) : progress
68
+
69
+ const ariaAttributes = {
70
+ 'aria-valuenow' :
71
+ ariaValueNow ?? ( progressAsNumber !== undefined && progressAsNumber >= 0 ? Math . round ( progressAsNumber ) : 0 ) ,
72
+ 'aria-valuemin' : 0 ,
73
+ 'aria-valuemax' : 100 ,
74
+ 'aria-valuetext' : ariaValueText ,
75
+ }
76
+
77
+ return (
78
+ < ProgressItem
79
+ { ...rest }
80
+ role = "progressbar"
81
+ aria-label = { ariaLabel }
82
+ ref = { forwardRef }
83
+ progress = { progress }
84
+ { ...ariaAttributes }
85
+ />
86
+ )
87
+ } ,
88
+ )
89
+
90
+ Item . displayName = 'ProgressBar.Item'
91
+
63
92
export type ProgressBarProps = React . HTMLAttributes < HTMLSpanElement > & { bg ?: string } & StyledProgressContainerProps &
64
93
ProgressProp
65
94
66
95
export const ProgressBar = forwardRef < HTMLSpanElement , ProgressBarProps > (
67
96
(
68
- { animated, progress, bg = 'success.emphasis' , barSize = 'default' , children, ...rest } : ProgressBarProps ,
97
+ {
98
+ animated,
99
+ progress,
100
+ bg = 'success.emphasis' ,
101
+ barSize = 'default' ,
102
+ children,
103
+ 'aria-label' : ariaLabel ,
104
+ 'aria-valuenow' : ariaValueNow ,
105
+ 'aria-valuetext' : ariaValueText ,
106
+ ...rest
107
+ } : ProgressBarProps ,
69
108
forwardRef ,
70
109
) => {
71
110
if ( children && progress ) {
72
111
throw new Error ( 'You should pass `progress` or children, not both.' )
73
112
}
74
113
75
- warning (
76
- children &&
77
- typeof ( rest as React . AriaAttributes ) [ 'aria-valuenow' ] === 'undefined' &&
78
- typeof ( rest as React . AriaAttributes ) [ 'aria-valuetext' ] === 'undefined' ,
79
- 'Expected `aria-valuenow` or `aria-valuetext` to be provided to <ProgressBar>. Provide one of these values so screen reader users can determine the current progress. This warning will become an error in the next major release.' ,
80
- )
81
-
82
- const progressAsNumber = typeof progress === 'string' ? parseInt ( progress , 10 ) : progress
83
-
84
- const ariaAttributes = {
85
- 'aria-valuenow' : progressAsNumber ? Math . round ( progressAsNumber ) : undefined ,
86
- 'aria-valuemin' : 0 ,
87
- 'aria-valuemax' : 100 ,
88
- 'aria-valuetext' : progressAsNumber ? `${ Math . round ( progressAsNumber ) } %` : undefined ,
89
- }
114
+ // Get the number of non-empty nodes passed as children, this will exclude
115
+ // booleans, null, and undefined
116
+ const validChildren = React . Children . toArray ( children ) . length
90
117
91
118
return (
92
- < ProgressContainer ref = { forwardRef } role = "progressbar" barSize = { barSize } { ...ariaAttributes } { ...rest } >
93
- { children ?? < Item data-animated = { animated } progress = { progress } bg = { bg } /> }
119
+ < ProgressContainer ref = { forwardRef } barSize = { barSize } { ...rest } >
120
+ { validChildren ? (
121
+ children
122
+ ) : (
123
+ < Item
124
+ data-animated = { animated }
125
+ progress = { progress }
126
+ aria-label = { ariaLabel }
127
+ aria-valuenow = { ariaValueNow }
128
+ aria-valuetext = { ariaValueText }
129
+ bg = { bg }
130
+ />
131
+ ) }
94
132
</ ProgressContainer >
95
133
)
96
134
} ,
0 commit comments