@@ -5,7 +5,6 @@ import {width} from 'styled-system'
55import { get } from '../constants'
66import type { SxProp } from '../sx'
77import sx from '../sx'
8- import { warning } from '../utils/warning'
98
109type ProgressProp = {
1110 progress ?: string | number
@@ -17,7 +16,7 @@ const shimmer = keyframes`
1716 to { mask-position: 0%; }
1817`
1918
20- export const Item = styled . span < ProgressProp & SxProp > `
19+ const ProgressItem = styled . span < ProgressProp & SxProp > `
2120 width: ${ props => ( props . progress ? `${ props . progress } %` : 0 ) } ;
2221 background-color: ${ props => get ( `colors.${ props . bg || 'success.emphasis' } ` ) } ;
2322
@@ -34,8 +33,6 @@ export const Item = styled.span<ProgressProp & SxProp>`
3433 ${ sx } ;
3534`
3635
37- Item . displayName = 'ProgressBar.Item'
38-
3936const sizeMap = {
4037 small : '5px' ,
4138 large : '10px' ,
@@ -60,37 +57,78 @@ const ProgressContainer = styled.span<StyledProgressContainerProps>`
6057 ${ sx } ;
6158`
6259
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+
6392export type ProgressBarProps = React . HTMLAttributes < HTMLSpanElement > & { bg ?: string } & StyledProgressContainerProps &
6493 ProgressProp
6594
6695export const ProgressBar = forwardRef < HTMLSpanElement , ProgressBarProps > (
6796 (
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 ,
69108 forwardRef ,
70109 ) => {
71110 if ( children && progress ) {
72111 throw new Error ( 'You should pass `progress` or children, not both.' )
73112 }
74113
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
90117
91118 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+ ) }
94132 </ ProgressContainer >
95133 )
96134 } ,
0 commit comments