diff --git a/.changeset/daterangeinput-trigger-no-longer-emits-invalid-a-d9dw.md b/.changeset/daterangeinput-trigger-no-longer-emits-invalid-a-d9dw.md new file mode 100644 index 000000000000..e79f12e706de --- /dev/null +++ b/.changeset/daterangeinput-trigger-no-longer-emits-invalid-a-d9dw.md @@ -0,0 +1,6 @@ +--- +'@astryxdesign/core': patch +--- + +[fix] DateRangeInput trigger no longer emits invalid aria-required on its button role +@alex-js-ltd diff --git a/packages/core/src/DateRangeInput/DateRangeInput.test.tsx b/packages/core/src/DateRangeInput/DateRangeInput.test.tsx index e6baa64d1d08..ff9c4971c488 100644 --- a/packages/core/src/DateRangeInput/DateRangeInput.test.tsx +++ b/packages/core/src/DateRangeInput/DateRangeInput.test.tsx @@ -92,7 +92,10 @@ describe('DateRangeInput', () => { expect(screen.getByText('Range')).toBeInTheDocument(); }); - it('sets aria-required when isRequired is true', () => { + it('does not put aria-required on the trigger button even when isRequired is true', () => { + // aria-required is not a supported attribute for role="button" (axe: + // aria-allowed-attr, WCAG 4.1.2) — the trigger is a plain button, not an + // editable/selectable widget role like textbox or combobox. render( { />, ); const trigger = getButton(/Range/); - expect(trigger).toHaveAttribute('aria-required', 'true'); + expect(trigger).not.toHaveAttribute('aria-required'); }); it('does not set aria-required when isRequired is false', () => { @@ -111,6 +114,22 @@ describe('DateRangeInput', () => { expect(trigger).not.toHaveAttribute('aria-required'); }); + it('exposes required state via the trigger accessible name instead', () => { + // With aria-required unusable on role="button", the required state must + // still reach assistive tech — via the accessible name (aria-label), + // which is legal on any role. + render( + {}} + />, + ); + const trigger = getButton(/Range/); + expect(trigger).toHaveAccessibleName(/Required/); + }); + it('disables trigger when isDisabled is true', () => { render(