diff --git a/packages/react-core/src/components/FormSelect/FormSelect.tsx b/packages/react-core/src/components/FormSelect/FormSelect.tsx index 0e909bbeadc..4703b82c523 100644 --- a/packages/react-core/src/components/FormSelect/FormSelect.tsx +++ b/packages/react-core/src/components/FormSelect/FormSelect.tsx @@ -31,7 +31,7 @@ export interface FormSelectProps onFocus?: (event: React.FormEvent) => void; /** Optional callback for updating when selection changes */ onChange?: (event: React.FormEvent, value: string) => void; - /** Custom flag to show that the FormSelect requires an associated id or aria-label. */ + /** Accessible label. Required unless an associated id or aria-labelledby is specified. */ 'aria-label'?: string; /** Value to overwrite the randomly generated data-ouia-component-id.*/ ouiaId?: number | string; @@ -43,9 +43,9 @@ class FormSelect extends Component { static displayName = 'FormSelect'; constructor(props: FormSelectProps) { super(props); - if (!props.id && !props['aria-label']) { + if (!props.id && !props['aria-label'] && !props['aria-labelledby']?.trim()) { // eslint-disable-next-line no-console - console.error('FormSelect requires either an id or aria-label to be specified'); + console.error('FormSelect requires an id, aria-label, or aria-labelledby to be specified'); } } diff --git a/packages/react-core/src/components/FormSelect/__tests__/FormSelect.test.tsx b/packages/react-core/src/components/FormSelect/__tests__/FormSelect.test.tsx index 347a086492c..56c3012bfa1 100644 --- a/packages/react-core/src/components/FormSelect/__tests__/FormSelect.test.tsx +++ b/packages/react-core/src/components/FormSelect/__tests__/FormSelect.test.tsx @@ -186,4 +186,45 @@ describe('FormSelect', () => { expect(myMock).toHaveBeenCalled(); expect(myMock.mock.calls[0][1]).toEqual('mr'); }); + + test.each(['select-label', ' select-label \t'])( + 'uses aria-labelledby %p without generating a console error', + (labelledBy) => { + const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {}); + + try { + render( + <> + Title + + + + + ); + + expect(screen.getByRole('combobox', { name: 'Title' })).toHaveAttribute('aria-labelledby', labelledBy); + expect(consoleError).not.toHaveBeenCalled(); + } finally { + consoleError.mockRestore(); + } + } + ); + + test.each(['', ' ', '\t\n'])('warns when aria-labelledby is %p and no other label is provided', (labelledBy) => { + const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {}); + + try { + render( + + + + ); + + expect(consoleError).toHaveBeenCalledWith( + 'FormSelect requires an id, aria-label, or aria-labelledby to be specified' + ); + } finally { + consoleError.mockRestore(); + } + }); });