aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/app
diff options
context:
space:
mode:
authorRevanshu Paliwal <revanshu.paliwal@sonarsource.com>2023-03-30 11:46:55 +0200
committersonartech <sonartech@sonarsource.com>2023-03-30 20:03:07 +0000
commit2383bd4877bc4c364c7e0a2912330fd6197978b3 (patch)
tree35f883be30c0ba13bb31b7f9aac1e9f4dc6ad5fd /server/sonar-web/src/main/js/app
parentf3b29dddf69bf05a6889b5812cf74de89bfd1df6 (diff)
downloadsonarqube-2383bd4877bc4c364c7e0a2912330fd6197978b3.tar.gz
sonarqube-2383bd4877bc4c364c7e0a2912330fd6197978b3.zip
SONAR-18918 Fixing accessibility issues in global search
Diffstat (limited to 'server/sonar-web/src/main/js/app')
-rw-r--r--server/sonar-web/src/main/js/app/components/global-search/GlobalSearch.tsx53
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/branch-like/BranchLikeNavigation.tsx77
2 files changed, 70 insertions, 60 deletions
diff --git a/server/sonar-web/src/main/js/app/components/global-search/GlobalSearch.tsx b/server/sonar-web/src/main/js/app/components/global-search/GlobalSearch.tsx
index 605b251614f..131c63ce23c 100644
--- a/server/sonar-web/src/main/js/app/components/global-search/GlobalSearch.tsx
+++ b/server/sonar-web/src/main/js/app/components/global-search/GlobalSearch.tsx
@@ -31,6 +31,7 @@ import {
import { debounce, uniqBy } from 'lodash';
import * as React from 'react';
import { getSuggestions } from '../../../api/components';
+import FocusOutHandler from '../../../components/controls/FocusOutHandler';
import OutsideClickHandler from '../../../components/controls/OutsideClickHandler';
import Tooltip from '../../../components/controls/Tooltip';
import { Router, withRouter } from '../../../components/hoc/withRouter';
@@ -39,6 +40,7 @@ import { isInput, isShortcut } from '../../../helpers/keyboardEventHelpers';
import { KeyboardKeys } from '../../../helpers/keycodes';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { getKeyboardShortcutEnabled } from '../../../helpers/preferences';
+import { scrollToElement } from '../../../helpers/scrolling';
import { getComponentOverviewUrl } from '../../../helpers/urls';
import { ComponentQualifier } from '../../../types/component';
import { Dict } from '../../../types/types';
@@ -277,7 +279,12 @@ export class GlobalSearch extends React.PureComponent<Props, State> {
const node = this.nodes[this.state.selected];
if (node && this.node) {
- node.scrollIntoView();
+ // using scrollIntoView here is creating some weird scroll behaviour when scrolling
+ scrollToElement(node, {
+ topOffset: 30,
+ bottomOffset: 30,
+ parent: this.node,
+ });
}
}
};
@@ -357,25 +364,10 @@ export class GlobalSearch extends React.PureComponent<Props, State> {
render() {
const { open, query, results, more, loadingMore, selected, loading } = this.state;
- if (!open && !query) {
- return (
- <Tooltip mouseEnterDelay={INTERACTIVE_TOOLTIP_DELAY} overlay={translate('search_verb')}>
- <InteractiveIcon
- className="it__search-icon"
- Icon={MenuSearchIcon}
- aria-label={translate('search_verb')}
- currentColor={true}
- onClick={this.handleFocus}
- size="medium"
- />
- </Tooltip>
- );
- }
-
const list = this.getPlainComponentsList(results, more);
const search = (
- <div role="search" className="sw-min-w-abs-200 sw-max-w-abs-350 sw-w-full">
+ <div className="sw-min-w-abs-200 sw-max-w-abs-350 sw-w-full">
<Popup
allowResizing={true}
overlay={
@@ -385,6 +377,7 @@ export class GlobalSearch extends React.PureComponent<Props, State> {
maxHeight="38rem"
innerRef={(node: HTMLUListElement | null) => (this.node = node)}
size="auto"
+ aria-owns="global-search-input"
>
<GlobalSearchResults
query={query}
@@ -409,6 +402,7 @@ export class GlobalSearch extends React.PureComponent<Props, State> {
zLevel={PopupZLevel.Global}
>
<InputSearch
+ id="global-search-input"
className="sw-w-full"
autoFocus={open}
innerRef={this.searchInputRef}
@@ -428,10 +422,27 @@ export class GlobalSearch extends React.PureComponent<Props, State> {
</div>
);
- return open ? (
- <OutsideClickHandler onClickOutside={this.handleClickOutside}>{search}</OutsideClickHandler>
- ) : (
- search
+ return (
+ <form role="search">
+ {!open && !query ? (
+ <Tooltip mouseEnterDelay={INTERACTIVE_TOOLTIP_DELAY} overlay={translate('search_verb')}>
+ <InteractiveIcon
+ className="it__search-icon"
+ Icon={MenuSearchIcon}
+ aria-label={translate('search_verb')}
+ currentColor={true}
+ onClick={this.handleFocus}
+ size="medium"
+ />
+ </Tooltip>
+ ) : (
+ <FocusOutHandler onFocusOut={this.handleClickOutside}>
+ <OutsideClickHandler onClickOutside={this.handleClickOutside}>
+ {search}
+ </OutsideClickHandler>
+ </FocusOutHandler>
+ )}
+ </form>
);
}
}
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/BranchLikeNavigation.tsx b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/BranchLikeNavigation.tsx
index b8296bd4355..db755f32bd4 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/BranchLikeNavigation.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/BranchLikeNavigation.tsx
@@ -20,6 +20,7 @@
import { ButtonSecondary, Popup, PopupPlacement, PopupZLevel } from 'design-system';
import * as React from 'react';
import EscKeydownHandler from '../../../../../components/controls/EscKeydownHandler';
+import FocusOutHandler from '../../../../../components/controls/FocusOutHandler';
import OutsideClickHandler from '../../../../../components/controls/OutsideClickHandler';
import { AlmKeys, ProjectAlmBindingResponse } from '../../../../../types/alm-settings';
import { BranchLike } from '../../../../../types/branch-like';
@@ -63,50 +64,48 @@ export function BranchLikeNavigation(props: BranchLikeNavigationProps) {
<CurrentBranchLike component={component} currentBranchLike={currentBranchLike} />
);
+ const handleOutsideClick = () => {
+ setIsMenuOpen(false);
+ };
+
return (
<div className="sw-flex sw-items-center sw-ml-2 it__branch-like-navigation-toggler-container">
- <EscKeydownHandler
- onKeydown={() => {
- setIsMenuOpen(false);
- }}
+ <Popup
+ allowResizing={true}
+ overlay={
+ isMenuOpen && (
+ <FocusOutHandler onFocusOut={handleOutsideClick}>
+ <EscKeydownHandler onKeydown={handleOutsideClick}>
+ <OutsideClickHandler onClickOutside={handleOutsideClick}>
+ <Menu
+ branchLikes={branchLikes}
+ canAdminComponent={canAdminComponent}
+ component={component}
+ currentBranchLike={currentBranchLike}
+ onClose={() => {
+ setIsMenuOpen(false);
+ }}
+ />
+ </OutsideClickHandler>
+ </EscKeydownHandler>
+ </FocusOutHandler>
+ )
+ }
+ placement={PopupPlacement.BottomLeft}
+ zLevel={PopupZLevel.Global}
>
- <OutsideClickHandler
- onClickOutside={() => {
- setIsMenuOpen(false);
+ <ButtonSecondary
+ className="sw-max-w-abs-350"
+ onClick={() => {
+ setIsMenuOpen(!isMenuOpen);
}}
+ disabled={!isMenuEnabled}
+ aria-expanded={isMenuOpen}
+ aria-haspopup="menu"
>
- <Popup
- allowResizing={true}
- overlay={
- isMenuOpen && (
- <Menu
- branchLikes={branchLikes}
- canAdminComponent={canAdminComponent}
- component={component}
- currentBranchLike={currentBranchLike}
- onClose={() => {
- setIsMenuOpen(false);
- }}
- />
- )
- }
- placement={PopupPlacement.BottomLeft}
- zLevel={PopupZLevel.Global}
- >
- <ButtonSecondary
- className="sw-max-w-abs-350"
- onClick={() => {
- setIsMenuOpen(!isMenuOpen);
- }}
- disabled={!isMenuEnabled}
- aria-expanded={isMenuOpen}
- aria-haspopup="menu"
- >
- {currentBranchLikeElement}
- </ButtonSecondary>
- </Popup>
- </OutsideClickHandler>
- </EscKeydownHandler>
+ {currentBranchLikeElement}
+ </ButtonSecondary>
+ </Popup>
<div className="sw-ml-2">
<BranchHelpTooltip