diff --git a/packages/react/src/ProgressBar/ProgressBar.stories.tsx b/packages/react/src/ProgressBar/ProgressBar.stories.tsx index fb8c4699fe0..725fa9f9ed2 100644 --- a/packages/react/src/ProgressBar/ProgressBar.stories.tsx +++ b/packages/react/src/ProgressBar/ProgressBar.stories.tsx @@ -1,7 +1,7 @@ import React, {useEffect} from 'react' import type {Meta} from '@storybook/react' import {ProgressBar} from '..' -import type {ProgressBarBaseProps} from './ProgressBar' +import type {ProgressBarProps} from './ProgressBar' const sectionColorsDefault = [ 'success.emphasis', @@ -19,7 +19,7 @@ export default { export const Default = () => -export const Playground = ({sections, ...args}: ProgressBarBaseProps & {sections: number}) => { +export const Playground = ({sections, ...args}: ProgressBarProps & {sections: number}) => { const [sectionColors, setSectionColors] = React.useState(sectionColorsDefault) useEffect(() => { diff --git a/packages/react/src/ProgressBar/ProgressBar.tsx b/packages/react/src/ProgressBar/ProgressBar.tsx index ccfa2f06926..de9450fdd5e 100644 --- a/packages/react/src/ProgressBar/ProgressBar.tsx +++ b/packages/react/src/ProgressBar/ProgressBar.tsx @@ -73,7 +73,6 @@ const ProgressContainer = toggleStyledComponent( ) export type ProgressBarItems = React.HTMLAttributes & { - 'aria-label': string className?: string } & ProgressProp & SxProp @@ -83,6 +82,7 @@ export const Item = forwardRef( { progress, 'aria-label': ariaLabel, + 'aria-hidden': ariaHidden, 'aria-valuenow': ariaValueNow, 'aria-valuetext': ariaValueText, className, @@ -110,6 +110,24 @@ export const Item = forwardRef( styles[progressBarWidth] = progress ? `${progress}%` : '0%' styles[progressBarBg] = (bgType && `var(--bgColor-${bgType[0]}-${bgType[1]})`) || 'var(--bgColor-success-emphasis)' + if (__DEV__) { + /** + * The Linter yells because it thinks this conditionally calls an effect, + * but since this is a compile-time flag and not a runtime conditional + * this is safe, and ensures the entire effect is kept out of prod builds + * shaving precious bytes from the output, and avoiding mounting a noop effect + */ + // eslint-disable-next-line react-hooks/rules-of-hooks + React.useEffect(() => { + if (!ariaHidden && !ariaLabel) { + // eslint-disable-next-line no-console + console.warn( + 'This component should include an aria-label or should be aria-hidden if surrounding text can be used to perceive the progress.', + ) + } + }, [ariaHidden, ariaLabel]) + } + return ( ( Item.displayName = 'ProgressBar.Item' -export type ProgressBarBaseProps = Omit< - React.HTMLAttributes & { - bg?: string - className?: string - } & StyledProgressContainerProps & - ProgressProp, - 'children' | 'aria-label' -> - -export type WithChildren = { - children: React.ReactNode - 'aria-label'?: never -} - -export type WithoutChildren = { - children?: never - 'aria-label': string -} - -export type ProgressBarProps = ProgressBarBaseProps & (WithChildren | WithoutChildren) +export type ProgressBarProps = React.HTMLAttributes & { + bg?: string + className?: string +} & StyledProgressContainerProps & + ProgressProp export const ProgressBar = forwardRef((props, forwardRef) => { const { @@ -158,6 +161,7 @@ export const ProgressBar = forwardRef((props, 'aria-label': ariaLabel, 'aria-valuenow': ariaValueNow, 'aria-valuetext': ariaValueText, + 'aria-hidden': ariaHidden, className, ...rest } = props @@ -188,9 +192,10 @@ export const ProgressBar = forwardRef((props, )} diff --git a/packages/react/src/__tests__/ProgressBar.test.tsx b/packages/react/src/__tests__/ProgressBar.test.tsx index 3406d659fe5..5adcca74f0b 100644 --- a/packages/react/src/__tests__/ProgressBar.test.tsx +++ b/packages/react/src/__tests__/ProgressBar.test.tsx @@ -6,6 +6,16 @@ import axe from 'axe-core' import {FeatureFlags} from '../FeatureFlags' describe('ProgressBar', () => { + const mockWarningFn = jest.fn() + + beforeEach(() => { + jest.spyOn(global.console, 'warn').mockImplementation(mockWarningFn) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + behavesAsComponent({ Component: ProgressBar, toRender: () => , @@ -112,4 +122,19 @@ describe('ProgressBar', () => { expect(getByRole('progressbar')).toHaveAttribute('aria-valuenow', '0') }) + + it('should warn users if aria-label is not provided', () => { + HTMLRender() + expect(mockWarningFn).toHaveBeenCalled() + }) + + it('should not warn users if aria-label is not provided but aria-hidden is', () => { + HTMLRender() + expect(mockWarningFn).not.toHaveBeenCalled() + }) + + it('should not warn users if aria-label is provided', () => { + HTMLRender() + expect(mockWarningFn).not.toHaveBeenCalled() + }) })