diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2024-07-29 18:38:22 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-07-30 20:02:34 +0000 |
commit | 6af98df51f5f85bb47e3661a471637133cdf97f2 (patch) | |
tree | ca704d4d69dbf7f055610d39562546d3e32bc6c7 /server | |
parent | b6c22b44e6cdb452270bc52bf04b854b89df55e9 (diff) | |
download | sonarqube-6af98df51f5f85bb47e3661a471637133cdf97f2.tar.gz sonarqube-6af98df51f5f85bb47e3661a471637133cdf97f2.zip |
SONAR-22306 Fix a11y of subnavigation components
Diffstat (limited to 'server')
5 files changed, 41 insertions, 36 deletions
diff --git a/server/sonar-web/design-system/src/components/subnavigation/SubnavigationItem.tsx b/server/sonar-web/design-system/src/components/subnavigation/SubnavigationItem.tsx index 0d03117246a..1059fda1364 100644 --- a/server/sonar-web/design-system/src/components/subnavigation/SubnavigationItem.tsx +++ b/server/sonar-web/design-system/src/components/subnavigation/SubnavigationItem.tsx @@ -28,15 +28,17 @@ import NavLink, { NavLinkProps } from '../NavLink'; interface Props { active?: boolean; + ariaCurrent?: boolean; children: ReactNode; className?: string; + id?: string; innerRef?: (node: HTMLAnchorElement) => void; onClick: (value?: string) => void; value?: string; } export function SubnavigationItem(props: Readonly<Props>) { - const { active, className, children, innerRef, onClick, value } = props; + const { active, ariaCurrent, className, children, id, innerRef, onClick, value } = props; const handleClick = useCallback( (e: SyntheticEvent<HTMLAnchorElement>) => { e.preventDefault(); @@ -46,9 +48,11 @@ export function SubnavigationItem(props: Readonly<Props>) { ); return ( <StyledSubnavigationItem + aria-current={ariaCurrent} className={classNames({ active }, className)} data-testid="js-subnavigation-item" href="#" + id={id} onClick={handleClick} ref={innerRef} > diff --git a/server/sonar-web/src/main/js/apps/component-measures/__tests__/ComponentMeasures-it.tsx b/server/sonar-web/src/main/js/apps/component-measures/__tests__/ComponentMeasures-it.tsx index 2329586d95b..6cc9c75fe76 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/__tests__/ComponentMeasures-it.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/__tests__/ComponentMeasures-it.tsx @@ -69,7 +69,7 @@ describe('rendering', () => { // Overview. expect(ui.seeDataAsListLink.get()).toBeInTheDocument(); - expect(ui.overviewDomainBtn.get()).toHaveAttribute('aria-current', 'true'); + expect(ui.overviewDomainLink.get()).toHaveAttribute('aria-current', 'true'); expect(ui.bubbleChart.get()).toBeInTheDocument(); expect(within(ui.bubbleChart.get()).getAllByRole('link')).toHaveLength(8); expect(ui.newCodePeriodTxt.get()).toBeInTheDocument(); @@ -98,7 +98,7 @@ describe('rendering', () => { 'Maintainability Rating metric.has_rating_X.E', 'Effort to Reach Maintainability Rating A work_duration.x_minutes.1', ].forEach((measure) => { - expect(ui.measureBtn(measure).get()).toBeInTheDocument(); + expect(ui.measureLink(measure).get()).toBeInTheDocument(); }); }); @@ -123,7 +123,7 @@ describe('rendering', () => { 'Maintainability Rating metric.has_rating_X.E', 'Effort to Reach Maintainability Rating A work_duration.x_minutes.1', ].forEach((measure) => { - expect(ui.measureBtn(measure).get()).toBeInTheDocument(); + expect(ui.measureLink(measure).get()).toBeInTheDocument(); }); expect(screen.getByText('overview.missing_project_dataTRK')).toBeInTheDocument(); }); @@ -207,7 +207,7 @@ describe('rendering', () => { 'component_measures.metric.new_accepted_issues.name 1', 'component_measures.metric.false_positive_issues.name 1', ].forEach((measure) => { - expect(ui.measureBtn(measure).get()).toBeInTheDocument(); + expect(ui.measureLink(measure).get()).toBeInTheDocument(); }); }); @@ -308,7 +308,7 @@ describe('rendering', () => { expect(ui.goToActivityLink.query()).not.toBeInTheDocument(); await user.click( - ui.measureBtn('component_measures.metric.maintainability_issues.name 2').get(), + ui.measureLink('component_measures.metric.maintainability_issues.name 2').get(), ); expect(ui.goToActivityLink.get()).toHaveAttribute( 'href', @@ -344,7 +344,7 @@ describe('navigation', () => { await user.click(ui.maintainabilityDomainBtn.get()); await user.click( - ui.measureBtn('component_measures.metric.maintainability_issues.name 2').get(), + ui.measureLink('component_measures.metric.maintainability_issues.name 2').get(), ); expect( within(ui.measuresRow('folderA').get()).getByRole('cell', { name: '2' }), @@ -377,7 +377,7 @@ describe('navigation', () => { await user.click(ui.maintainabilityDomainBtn.get()); await user.click( - ui.measureBtn('component_measures.metric.maintainability_issues.name 2').get(), + ui.measureLink('component_measures.metric.maintainability_issues.name 2').get(), ); // Click list option in view select @@ -401,7 +401,7 @@ describe('navigation', () => { await ui.appLoaded(); await user.click(ui.maintainabilityDomainBtn.get()); - await user.click(ui.measureBtn('Maintainability Rating metric.has_rating_X.E').get()); + await user.click(ui.measureLink('Maintainability Rating metric.has_rating_X.E').get()); // Click treemap option in view select await user.click(ui.viewSelect.get()); @@ -427,7 +427,7 @@ describe('navigation', () => { // Drilldown to the file level. await user.click(ui.maintainabilityDomainBtn.get()); await user.click( - ui.measureBtn('component_measures.metric.maintainability_issues.name 2').get(), + ui.measureLink('component_measures.metric.maintainability_issues.name 2').get(), ); await ui.arrowDown(); // Select the 1st element ("folderA") @@ -472,7 +472,7 @@ describe('redirects', () => { const { ui } = getPageObject(); renderMeasuresApp('component_measures/metric/bugs?id=foo'); await ui.appLoaded(); - expect(ui.measureBtn('component_measures.metric.bugs.name 0').get()).toHaveAttribute( + expect(ui.measureLink('component_measures.metric.bugs.name 0').get()).toHaveAttribute( 'aria-current', 'true', ); @@ -482,10 +482,9 @@ describe('redirects', () => { const { ui } = getPageObject(); renderMeasuresApp('component_measures/metric/security_issues?id=foo'); await ui.appLoaded(); - expect(ui.measureBtn('component_measures.metric.security_issues.name 1').get()).toHaveAttribute( - 'aria-current', - 'true', - ); + expect( + ui.measureLink('component_measures.metric.security_issues.name 1').get(), + ).toHaveAttribute('aria-current', 'true'); }); it('should redirect old domain route', async () => { @@ -547,7 +546,7 @@ function getPageObject() { newCodePeriodTxt: byText('component_measures.leak_legend.new_code'), // Navigation - overviewDomainBtn: byRole('button', { + overviewDomainLink: byRole('link', { name: 'component_measures.overview.project_overview.subnavigation', }), releasabilityDomainBtn: byRole('button', { @@ -580,7 +579,7 @@ function getPageObject() { issuesDomainBtn: byRole('button', { name: 'Issues component_measures.domain_subnavigation.Issues.help', }), - measureBtn: (name: string) => byRole('button', { name }), + measureLink: (name: string) => byRole('link', { name }), // Measure content measuresTable: byRole('table'), diff --git a/server/sonar-web/src/main/js/apps/component-measures/sidebar/DomainSubnavigation.tsx b/server/sonar-web/src/main/js/apps/component-measures/sidebar/DomainSubnavigation.tsx index a90b976c8d5..ae2fd362713 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/sidebar/DomainSubnavigation.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/sidebar/DomainSubnavigation.tsx @@ -18,7 +18,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { - BareButton, HelperHintIcon, SubnavigationAccordion, SubnavigationItem, @@ -87,10 +86,13 @@ export default function DomainSubnavigation(props: Readonly<Props>) { id={`measure-${domain.name}`} > {hasOverview(domain.name) && ( - <SubnavigationItem active={domain.name === selected} onClick={onChange} value={domain.name}> - <BareButton aria-current={domain.name === selected}> - {translate('component_measures.domain_overview')} - </BareButton> + <SubnavigationItem + active={domain.name === selected} + ariaCurrent={domain.name === selected} + onClick={onChange} + value={domain.name} + > + {translate('component_measures.domain_overview')} </SubnavigationItem> )} diff --git a/server/sonar-web/src/main/js/apps/component-measures/sidebar/DomainSubnavigationItem.tsx b/server/sonar-web/src/main/js/apps/component-measures/sidebar/DomainSubnavigationItem.tsx index 7bd33db86cd..791b6025f32 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/sidebar/DomainSubnavigationItem.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/sidebar/DomainSubnavigationItem.tsx @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { BareButton, SubnavigationItem } from 'design-system'; +import { SubnavigationItem } from 'design-system'; import React from 'react'; import { MeasureEnhanced } from '../../../types/types'; import SubnavigationMeasureValue from './SubnavigationMeasureValue'; @@ -37,15 +37,17 @@ export default function DomainSubnavigationItem({ }: Readonly<Props>) { const { key } = measure.metric; return ( - <SubnavigationItem active={key === selected} key={key} onClick={onChange} value={key}> - <BareButton - aria-current={key === selected} - className="sw-ml-2 sw-w-full sw-flex sw-justify-between" - id={`measure-${key}-name`} - > - {name} - <SubnavigationMeasureValue measure={measure} /> - </BareButton> + <SubnavigationItem + active={key === selected} + ariaCurrent={key === selected} + key={key} + onClick={onChange} + value={key} + className="sw-pl-2 sw-w-full sw-flex sw-justify-between" + id={`measure-${key}-name`} + > + {name} + <SubnavigationMeasureValue measure={measure} /> </SubnavigationItem> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/sidebar/Sidebar.tsx b/server/sonar-web/src/main/js/apps/component-measures/sidebar/Sidebar.tsx index 103d5ce0287..2370040305b 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/sidebar/Sidebar.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/sidebar/Sidebar.tsx @@ -20,7 +20,6 @@ import { withTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { - BareButton, LAYOUT_FOOTER_HEIGHT, LAYOUT_GLOBAL_NAV_HEIGHT, LAYOUT_PROJECT_NAV_HEIGHT, @@ -91,11 +90,10 @@ export default function Sidebar(props: Readonly<Props>) { <SubnavigationGroup> <SubnavigationItem active={isProjectOverview(selectedMetric)} + ariaCurrent={isProjectOverview(selectedMetric)} onClick={handleProjectOverviewClick} > - <BareButton aria-current={isProjectOverview(selectedMetric)}> - {translate('component_measures.overview', PROJECT_OVERVEW, 'subnavigation')} - </BareButton> + {translate('component_measures.overview', PROJECT_OVERVEW, 'subnavigation')} </SubnavigationItem> </SubnavigationGroup> |