diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2022-07-26 15:05:37 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-07-28 20:02:55 +0000 |
commit | d2d1034e10a78992a9d3aa3267dc770832646af1 (patch) | |
tree | d5b5b69794ea3e8a7254912a42beeddb2ce04601 /server | |
parent | 76b594f966759863e4b6763c6f6cc01fadf2fba9 (diff) | |
download | sonarqube-d2d1034e10a78992a9d3aa3267dc770832646af1.tar.gz sonarqube-d2d1034e10a78992a9d3aa3267dc770832646af1.zip |
SONAR-16683 [891539] Semantic html for the search results
Diffstat (limited to 'server')
6 files changed, 110 insertions, 89 deletions
diff --git a/server/sonar-web/src/main/js/app/components/search/Search.tsx b/server/sonar-web/src/main/js/app/components/search/Search.tsx index eb716f341e7..98996b99490 100644 --- a/server/sonar-web/src/main/js/app/components/search/Search.tsx +++ b/server/sonar-web/src/main/js/app/components/search/Search.tsx @@ -378,7 +378,7 @@ export class Search extends React.PureComponent<Props, State> { selected={this.state.selected} /> <div className="dropdown-bottom-hint"> - <div className="pull-right"> + <div className="pull-right" aria-hidden={true}> <ClockIcon className="little-spacer-right" size={12} /> {translate('recently_browsed')} </div> diff --git a/server/sonar-web/src/main/js/app/components/search/SearchResult.tsx b/server/sonar-web/src/main/js/app/components/search/SearchResult.tsx index 16f946915d7..c155d0bb86f 100644 --- a/server/sonar-web/src/main/js/app/components/search/SearchResult.tsx +++ b/server/sonar-web/src/main/js/app/components/search/SearchResult.tsx @@ -41,6 +41,7 @@ interface State { } const TOOLTIP_DELAY = 1000; +const MILLISECONDS_PER_SECOND = 1000; export default class SearchResult extends React.PureComponent<Props, State> { interval?: number; @@ -101,9 +102,11 @@ export default class SearchResult extends React.PureComponent<Props, State> { <li className={this.props.selected ? 'active' : undefined} key={component.key} - ref={node => this.props.innerRef(component.key, node)}> + ref={node => this.props.innerRef(component.key, node)} + role="option" + aria-selected={this.props.selected}> <Tooltip - mouseEnterDelay={TOOLTIP_DELAY / 1000} + mouseEnterDelay={TOOLTIP_DELAY / MILLISECONDS_PER_SECOND} overlay={component.key} placement="left" visible={this.state.tooltipVisible}> @@ -118,7 +121,8 @@ export default class SearchResult extends React.PureComponent<Props, State> { {component.match ? ( <span className="navbar-search-item-match" - // Safe: comes from the backend + // Safe: comes from the search engine, that injects bold tags into component names + // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{ __html: component.match }} /> ) : ( diff --git a/server/sonar-web/src/main/js/app/components/search/SearchResults.tsx b/server/sonar-web/src/main/js/app/components/search/SearchResults.tsx index 4b12eff31df..c0ccf411c86 100644 --- a/server/sonar-web/src/main/js/app/components/search/SearchResults.tsx +++ b/server/sonar-web/src/main/js/app/components/search/SearchResults.tsx @@ -41,39 +41,30 @@ export default function SearchResults(props: Props): React.ReactElement<Props> { sortQualifiers(qualifiers).forEach(qualifier => { const components = props.results[qualifier]; - if (components.length > 0 && renderedComponents.length > 0) { - renderedComponents.push(<li className="divider" key={`divider-${qualifier}`} />); - } - if (components.length > 0) { - renderedComponents.push( - <li className="menu-header" key={`header-${qualifier}`}> - {translate('qualifiers', qualifier)} - </li> - ); - } - - components.forEach(component => renderedComponents.push(props.renderResult(component))); + const more = props.more[qualifier]; - const more = props.more[qualifier]; - if (more !== undefined && more > 0) { renderedComponents.push( - <SearchShowMore - allowMore={props.allowMore} - key={`more-${qualifier}`} - loadingMore={props.loadingMore} - onMoreClick={props.onMoreClick} - onSelect={props.onSelect} - qualifier={qualifier} - selected={props.selected === `qualifier###${qualifier}`} - /> + <ul className="menu" key={`header-${qualifier}`} role="group"> + <li className="menu-header" role="presentation"> + {translate('qualifiers', qualifier)} + </li> + {components.map(component => props.renderResult(component))} + {more !== undefined && more > 0 && ( + <SearchShowMore + allowMore={props.allowMore} + key={`more-${qualifier}`} + loadingMore={props.loadingMore} + onMoreClick={props.onMoreClick} + onSelect={props.onSelect} + qualifier={qualifier} + selected={props.selected === `qualifier###${qualifier}`} + /> + )} + </ul> ); } }); - return renderedComponents.length > 0 ? ( - <ul className="menu">{renderedComponents}</ul> - ) : ( - props.renderNoResults() - ); + return renderedComponents.length > 0 ? <div>{renderedComponents}</div> : props.renderNoResults(); } diff --git a/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResult-test.tsx.snap b/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResult-test.tsx.snap index d4e19eaf97b..4cee1218fcd 100644 --- a/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResult-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResult-test.tsx.snap @@ -2,7 +2,9 @@ exports[`renders favorite 1`] = ` <li + aria-selected={false} key="foo" + role="option" > <Tooltip mouseEnterDelay={1} @@ -49,7 +51,9 @@ exports[`renders favorite 1`] = ` exports[`renders match 1`] = ` <li + aria-selected={false} key="foo" + role="option" > <Tooltip mouseEnterDelay={1} @@ -95,7 +99,9 @@ exports[`renders match 1`] = ` exports[`renders projects 1`] = ` <li + aria-selected={false} key="qwe" + role="option" > <Tooltip mouseEnterDelay={1} @@ -146,7 +152,9 @@ exports[`renders projects 1`] = ` exports[`renders recently browsed 1`] = ` <li + aria-selected={false} key="foo" + role="option" > <Tooltip mouseEnterDelay={1} @@ -192,7 +200,9 @@ exports[`renders recently browsed 1`] = ` exports[`renders selected 1`] = ` <li + aria-selected={false} key="foo" + role="option" > <Tooltip mouseEnterDelay={1} @@ -235,8 +245,10 @@ exports[`renders selected 1`] = ` exports[`renders selected 2`] = ` <li + aria-selected={true} className="active" key="foo" + role="option" > <Tooltip mouseEnterDelay={1} diff --git a/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResults-test.tsx.snap b/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResults-test.tsx.snap index 54e23479104..c0668213eed 100644 --- a/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResults-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResults-test.tsx.snap @@ -1,72 +1,82 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders "Show More" link 1`] = ` -<ul - className="menu" -> - <li - className="menu-header" +<div> + <ul + className="menu" key="header-TRK" + role="group" > - qualifiers.TRK - </li> - <span - key="foo" - > - foo - </span> - <span - key="bar" - > - bar - </span> - <SearchShowMore - allowMore={true} - key="more-TRK" - onMoreClick={[MockFunction]} - onSelect={[MockFunction]} - qualifier="TRK" - selected={false} - /> -</ul> + <li + className="menu-header" + role="presentation" + > + qualifiers.TRK + </li> + <span + key="foo" + > + foo + </span> + <span + key="bar" + > + bar + </span> + <SearchShowMore + allowMore={true} + key="more-TRK" + onMoreClick={[MockFunction]} + onSelect={[MockFunction]} + qualifier="TRK" + selected={false} + /> + </ul> +</div> `; exports[`renders different components and dividers between them 1`] = ` -<ul - className="menu" -> - <li - className="menu-header" +<div> + <ul + className="menu" key="header-FIL" + role="group" > - qualifiers.FIL - </li> - <span - key="zux" - > - zux - </span> - <li - className="divider" - key="divider-TRK" - /> - <li - className="menu-header" + <li + className="menu-header" + role="presentation" + > + qualifiers.FIL + </li> + <span + key="zux" + > + zux + </span> + </ul> + <ul + className="menu" key="header-TRK" + role="group" > - qualifiers.TRK - </li> - <span - key="foo" - > - foo - </span> - <span - key="bar" - > - bar - </span> -</ul> + <li + className="menu-header" + role="presentation" + > + qualifiers.TRK + </li> + <span + key="foo" + > + foo + </span> + <span + key="bar" + > + bar + </span> + </ul> +</div> `; exports[`should render no results 1`] = ` diff --git a/server/sonar-web/src/main/js/app/styles/components/menu.css b/server/sonar-web/src/main/js/app/styles/components/menu.css index 6ed64f7f2e6..567e5f9a18c 100644 --- a/server/sonar-web/src/main/js/app/styles/components/menu.css +++ b/server/sonar-web/src/main/js/app/styles/components/menu.css @@ -27,6 +27,10 @@ background-clip: padding-box; } +.menu + .menu { + border-top: 1px solid var(--barBorderColor); +} + .menu:focus { outline: none; } |