diff options
author | Wouter Admiraal <wouter.admiraal@sonarsource.com> | 2022-08-25 13:46:31 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-08-29 12:01:18 +0000 |
commit | 6304d93991af2397eb8c5ab665a61ea93434030e (patch) | |
tree | f040ba3628c800f0469790de39b3670c5b15a58e | |
parent | 9a57ed02f242fd387b1225e11391d3e9bb87cbfb (diff) | |
download | sonarqube-6304d93991af2397eb8c5ab665a61ea93434030e.tar.gz sonarqube-6304d93991af2397eb8c5ab665a61ea93434030e.zip |
SONAR-16738 [891611] Visual list is not marked up as list
7 files changed, 696 insertions, 582 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx index e4961f26995..7db00ac9c10 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx @@ -115,15 +115,16 @@ export default class Filter extends React.PureComponent<Props> { ); } - renderOption(option: Option) { + renderOption(option: Option, highlightable = false, lastHighlightable = false) { const { facet, getFacetValueForOption = defaultGetFacetValueForOption, value } = this.props; + const active = this.isSelected(option); const className = classNames( 'facet', 'search-navigator-facet', 'projects-facet', 'button-link', { - active: this.isSelected(option), + active, 'search-navigator-facet-half': this.props.halfWidth }, this.props.optionClassName @@ -139,26 +140,33 @@ export default class Filter extends React.PureComponent<Props> { option > value; return ( - <button - aria-label={this.props.renderAccessibleLabel(option)} - className={className} - data-key={option} - type="button" - tabIndex={0} + <li key={option} - onClick={this.handleClick} - role="checkbox" - aria-checked={this.isSelected(option) || isUnderSelectedOption}> - <span className="facet-name"> - {this.props.renderOption(option, this.isSelected(option) || isUnderSelectedOption)} - </span> - {facetValue != null && ( - <span className="facet-stat"> - {formatMeasure(facetValue, 'SHORT_INT')} - {this.renderOptionBar(facetValue)} + className={classNames({ + 'search-navigator-facet-worse-than-highlight': highlightable, + last: lastHighlightable, + active + })}> + <button + aria-label={this.props.renderAccessibleLabel(option)} + className={className} + data-key={option} + type="button" + tabIndex={0} + onClick={this.handleClick} + role="checkbox" + aria-checked={this.isSelected(option) || isUnderSelectedOption}> + <span className="facet-name"> + {this.props.renderOption(option, this.isSelected(option) || isUnderSelectedOption)} </span> - )} - </button> + {facetValue != null && ( + <span className="facet-stat"> + {formatMeasure(facetValue, 'SHORT_INT')} + {this.renderOptionBar(facetValue)} + </span> + )} + </button> + </li> ); } @@ -171,24 +179,26 @@ export default class Filter extends React.PureComponent<Props> { const insideHighlight = options.slice(highlightUnder, max); const afterHighlight = options.slice(max); return ( - <div className="search-navigator-facet-list projects-facet-list"> + <ul className="search-navigator-facet-list projects-facet-list"> {beforeHighlight.map(option => this.renderOption(option))} - <div className="search-navigator-facet-highlight-under-container"> - {insideHighlight.map(option => this.renderOption(option))} - </div> + {insideHighlight.map((option, i) => + this.renderOption(option, true, i === insideHighlight.length - 1) + )} {afterHighlight.map(option => this.renderOption(option))} - </div> - ); - } else { - return ( - <div className="search-navigator-facet-list projects-facet-list"> - {options.map(option => this.renderOption(option))} - </div> + </ul> ); } - } else { - return <div className="search-navigator-facet-empty">{translate('no_results')}</div>; + return ( + <ul className="search-navigator-facet-list projects-facet-list"> + {options.map(option => this.renderOption(option))} + </ul> + ); } + return ( + <div className="search-navigator-facet-empty"> + <em>{translate('projects.facets.no_available_filters_clear_others')}</em> + </div> + ); }; render() { diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/Filter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/Filter-test.tsx.snap index e45056ac4a0..891db262a5d 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/Filter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/Filter-test.tsx.snap @@ -5,35 +5,39 @@ exports[`highlights under 1`] = ` className="search-navigator-facet-box" data-key="foo" > - <div + <ul className="search-navigator-facet-list projects-facet-list" > - <button - aria-checked={false} - aria-label="1" - className="facet search-navigator-facet projects-facet button-link" - data-key={1} + <li + className="" key="1" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="1" + className="facet search-navigator-facet projects-facet button-link" + data-key={1} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 1 - </span> - </button> - <div - className="search-navigator-facet-highlight-under-container" + <span + className="facet-name" + > + 1 + </span> + </button> + </li> + <li + className="search-navigator-facet-worse-than-highlight" + key="2" > <button aria-checked={false} aria-label="2" className="facet search-navigator-facet projects-facet button-link" data-key={2} - key="2" onClick={[Function]} role="checkbox" tabIndex={0} @@ -45,12 +49,16 @@ exports[`highlights under 1`] = ` 2 </span> </button> + </li> + <li + className="search-navigator-facet-worse-than-highlight last" + key="3" + > <button aria-checked={false} aria-label="3" className="facet search-navigator-facet projects-facet button-link" data-key={3} - key="3" onClick={[Function]} role="checkbox" tabIndex={0} @@ -62,8 +70,8 @@ exports[`highlights under 1`] = ` 3 </span> </button> - </div> - </div> + </li> + </ul> </div> `; @@ -72,35 +80,39 @@ exports[`hightlights under selected 1`] = ` className="search-navigator-facet-box" data-key="foo" > - <div + <ul className="search-navigator-facet-list projects-facet-list" > - <button - aria-checked={false} - aria-label="1" - className="facet search-navigator-facet projects-facet button-link" - data-key={1} + <li + className="" key="1" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="1" + className="facet search-navigator-facet projects-facet button-link" + data-key={1} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 1 - </span> - </button> - <div - className="search-navigator-facet-highlight-under-container" + <span + className="facet-name" + > + 1 + </span> + </button> + </li> + <li + className="search-navigator-facet-worse-than-highlight active" + key="2" > <button aria-checked={true} aria-label="2" className="facet search-navigator-facet projects-facet button-link active" data-key={2} - key="2" onClick={[Function]} role="checkbox" tabIndex={0} @@ -112,12 +124,16 @@ exports[`hightlights under selected 1`] = ` 2 </span> </button> + </li> + <li + className="search-navigator-facet-worse-than-highlight last" + key="3" + > <button aria-checked={true} aria-label="3" className="facet search-navigator-facet projects-facet button-link" data-key={3} - key="3" onClick={[Function]} role="checkbox" tabIndex={0} @@ -129,8 +145,8 @@ exports[`hightlights under selected 1`] = ` 3 </span> </button> - </div> - </div> + </li> + </ul> </div> `; @@ -139,61 +155,73 @@ exports[`renders 1`] = ` className="search-navigator-facet-box" data-key="foo" > - <div + <ul className="search-navigator-facet-list projects-facet-list" > - <button - aria-checked={false} - aria-label="1" - className="facet search-navigator-facet projects-facet button-link" - data-key={1} + <li + className="" key="1" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="1" + className="facet search-navigator-facet projects-facet button-link" + data-key={1} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 1 - </span> - </button> - <button - aria-checked={false} - aria-label="2" - className="facet search-navigator-facet projects-facet button-link" - data-key={2} + <span + className="facet-name" + > + 1 + </span> + </button> + </li> + <li + className="" key="2" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="2" + className="facet search-navigator-facet projects-facet button-link" + data-key={2} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 2 - </span> - </button> - <button - aria-checked={false} - aria-label="3" - className="facet search-navigator-facet projects-facet button-link" - data-key={3} + <span + className="facet-name" + > + 2 + </span> + </button> + </li> + <li + className="" key="3" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="3" + className="facet search-navigator-facet projects-facet button-link" + data-key={3} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 3 - </span> - </button> - </div> + <span + className="facet-name" + > + 3 + </span> + </button> + </li> + </ul> </div> `; @@ -202,112 +230,124 @@ exports[`renders facet bar chart 1`] = ` className="search-navigator-facet-box" data-key="foo" > - <div + <ul className="search-navigator-facet-list projects-facet-list" > - <button - aria-checked={false} - aria-label="a" - className="facet search-navigator-facet projects-facet button-link" - data-key="a" + <li + className="" key="a" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" - > - a - </span> - <span - className="facet-stat" + <button + aria-checked={false} + aria-label="a" + className="facet search-navigator-facet projects-facet button-link" + data-key="a" + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 17 - <div - className="projects-facet-bar" + <span + className="facet-name" > + a + </span> + <span + className="facet-stat" + > + 17 <div - className="projects-facet-bar-inner" - style={ - Object { - "width": 42.5, + className="projects-facet-bar" + > + <div + className="projects-facet-bar-inner" + style={ + Object { + "width": 42.5, + } } - } - /> - </div> - </span> - </button> - <button - aria-checked={false} - aria-label="b" - className="facet search-navigator-facet projects-facet button-link" - data-key="b" + /> + </div> + </span> + </button> + </li> + <li + className="" key="b" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" - > - b - </span> - <span - className="facet-stat" + <button + aria-checked={false} + aria-label="b" + className="facet search-navigator-facet projects-facet button-link" + data-key="b" + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 15 - <div - className="projects-facet-bar" + <span + className="facet-name" + > + b + </span> + <span + className="facet-stat" > + 15 <div - className="projects-facet-bar-inner" - style={ - Object { - "width": 37.5, + className="projects-facet-bar" + > + <div + className="projects-facet-bar-inner" + style={ + Object { + "width": 37.5, + } } - } - /> - </div> - </span> - </button> - <button - aria-checked={false} - aria-label="c" - className="facet search-navigator-facet projects-facet button-link" - data-key="c" + /> + </div> + </span> + </button> + </li> + <li + className="" key="c" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" - > - c - </span> - <span - className="facet-stat" + <button + aria-checked={false} + aria-label="c" + className="facet search-navigator-facet projects-facet button-link" + data-key="c" + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 24 - <div - className="projects-facet-bar" + <span + className="facet-name" + > + c + </span> + <span + className="facet-stat" > + 24 <div - className="projects-facet-bar-inner" - style={ - Object { - "width": 60, + className="projects-facet-bar" + > + <div + className="projects-facet-bar-inner" + style={ + Object { + "width": 60, + } } - } - /> - </div> - </span> - </button> - </div> + /> + </div> + </span> + </button> + </li> + </ul> </div> `; @@ -317,61 +357,73 @@ exports[`renders header and footer 1`] = ` data-key="foo" > <header /> - <div + <ul className="search-navigator-facet-list projects-facet-list" > - <button - aria-checked={false} - aria-label="1" - className="facet search-navigator-facet projects-facet button-link" - data-key={1} + <li + className="" key="1" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="1" + className="facet search-navigator-facet projects-facet button-link" + data-key={1} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 1 - </span> - </button> - <button - aria-checked={false} - aria-label="2" - className="facet search-navigator-facet projects-facet button-link" - data-key={2} + <span + className="facet-name" + > + 1 + </span> + </button> + </li> + <li + className="" key="2" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="2" + className="facet search-navigator-facet projects-facet button-link" + data-key={2} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 2 - </span> - </button> - <button - aria-checked={false} - aria-label="3" - className="facet search-navigator-facet projects-facet button-link" - data-key={3} + <span + className="facet-name" + > + 2 + </span> + </button> + </li> + <li + className="" key="3" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="3" + className="facet search-navigator-facet projects-facet button-link" + data-key={3} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 3 - </span> - </button> - </div> + <span + className="facet-name" + > + 3 + </span> + </button> + </li> + </ul> <footer /> </div> `; @@ -381,61 +433,73 @@ exports[`renders multiple selected 1`] = ` className="search-navigator-facet-box" data-key="foo" > - <div + <ul className="search-navigator-facet-list projects-facet-list" > - <button - aria-checked={true} - aria-label="1" - className="facet search-navigator-facet projects-facet button-link active" - data-key={1} + <li + className="active" key="1" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={true} + aria-label="1" + className="facet search-navigator-facet projects-facet button-link active" + data-key={1} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 1 - </span> - </button> - <button - aria-checked={true} - aria-label="2" - className="facet search-navigator-facet projects-facet button-link active" - data-key={2} + <span + className="facet-name" + > + 1 + </span> + </button> + </li> + <li + className="active" key="2" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={true} + aria-label="2" + className="facet search-navigator-facet projects-facet button-link active" + data-key={2} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 2 - </span> - </button> - <button - aria-checked={false} - aria-label="3" - className="facet search-navigator-facet projects-facet button-link" - data-key={3} + <span + className="facet-name" + > + 2 + </span> + </button> + </li> + <li + className="" key="3" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="3" + className="facet search-navigator-facet projects-facet button-link" + data-key={3} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 3 - </span> - </button> - </div> + <span + className="facet-name" + > + 3 + </span> + </button> + </li> + </ul> </div> `; @@ -447,7 +511,9 @@ exports[`renders no results 1`] = ` <div className="search-navigator-facet-empty" > - no_results + <em> + projects.facets.no_available_filters_clear_others + </em> </div> </div> `; @@ -457,60 +523,72 @@ exports[`renders selected 1`] = ` className="search-navigator-facet-box" data-key="foo" > - <div + <ul className="search-navigator-facet-list projects-facet-list" > - <button - aria-checked={false} - aria-label="1" - className="facet search-navigator-facet projects-facet button-link" - data-key={1} + <li + className="" key="1" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="1" + className="facet search-navigator-facet projects-facet button-link" + data-key={1} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 1 - </span> - </button> - <button - aria-checked={true} - aria-label="2" - className="facet search-navigator-facet projects-facet button-link active" - data-key={2} + <span + className="facet-name" + > + 1 + </span> + </button> + </li> + <li + className="active" key="2" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={true} + aria-label="2" + className="facet search-navigator-facet projects-facet button-link active" + data-key={2} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 2 - </span> - </button> - <button - aria-checked={false} - aria-label="3" - className="facet search-navigator-facet projects-facet button-link" - data-key={3} + <span + className="facet-name" + > + 2 + </span> + </button> + </li> + <li + className="" key="3" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="3" + className="facet search-navigator-facet projects-facet button-link" + data-key={3} + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 3 - </span> - </button> - </div> + <span + className="facet-name" + > + 3 + </span> + </button> + </li> + </ul> </div> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap index c5301bbcb24..599f4d2d941 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap @@ -72,100 +72,112 @@ exports[`should render the languages facet with the selected languages 2`] = ` <FilterHeader name="projects.facets.languages" /> - <div + <ul className="search-navigator-facet-list projects-facet-list" > - <button - aria-checked={true} - aria-label="projects.facets.label_text_x.projects.facets.languages.Java" - className="facet search-navigator-facet projects-facet button-link active" - data-key="java" + <li + className="active" key="java" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={true} + aria-label="projects.facets.label_text_x.projects.facets.languages.Java" + className="facet search-navigator-facet projects-facet button-link active" + data-key="java" + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - <SearchableFilterOption - option={ - Object { - "key": "java", - "name": "Java", + <span + className="facet-name" + > + <SearchableFilterOption + option={ + Object { + "key": "java", + "name": "Java", + } } - } - optionKey="java" - /> - </span> - <span - className="facet-stat" - > - 39 - </span> - </button> - <button - aria-checked={true} - aria-label="projects.facets.label_text_x.projects.facets.languages.C#" - className="facet search-navigator-facet projects-facet button-link active" - data-key="cs" + optionKey="java" + /> + </span> + <span + className="facet-stat" + > + 39 + </span> + </button> + </li> + <li + className="active" key="cs" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={true} + aria-label="projects.facets.label_text_x.projects.facets.languages.C#" + className="facet search-navigator-facet projects-facet button-link active" + data-key="cs" + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - <SearchableFilterOption - option={ - Object { - "key": "cs", - "name": "C#", + <span + className="facet-name" + > + <SearchableFilterOption + option={ + Object { + "key": "cs", + "name": "C#", + } } - } - optionKey="cs" - /> - </span> - <span - className="facet-stat" - > - 4 - </span> - </button> - <button - aria-checked={false} - aria-label="projects.facets.label_text_x.projects.facets.languages.JavaScript" - className="facet search-navigator-facet projects-facet button-link" - data-key="js" + optionKey="cs" + /> + </span> + <span + className="facet-stat" + > + 4 + </span> + </button> + </li> + <li + className="" key="js" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={false} + aria-label="projects.facets.label_text_x.projects.facets.languages.JavaScript" + className="facet search-navigator-facet projects-facet button-link" + data-key="js" + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - <SearchableFilterOption - option={ - Object { - "key": "js", - "name": "JavaScript", + <span + className="facet-name" + > + <SearchableFilterOption + option={ + Object { + "key": "js", + "name": "JavaScript", + } } - } - optionKey="js" - /> - </span> - <span - className="facet-stat" - > - 1 - </span> - </button> - </div> + optionKey="js" + /> + </span> + <span + className="facet-stat" + > + 1 + </span> + </button> + </li> + </ul> <SearchableFilterFooter onQueryChange={[MockFunction]} options={ diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap index 94c5ca062ed..5b04154d8cf 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap @@ -157,82 +157,94 @@ exports[`should render the tags facet with the selected tags 2`] = ` <FilterHeader name="projects.facets.tags" /> - <div + <ul className="search-navigator-facet-list projects-facet-list" > - <button - aria-checked={true} - aria-label="projects.facets.label_text_x.projects.facets.tags.lang" - className="facet search-navigator-facet projects-facet button-link active" - data-key="lang" + <li + className="active" key="lang" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" + <button + aria-checked={true} + aria-label="projects.facets.label_text_x.projects.facets.tags.lang" + className="facet search-navigator-facet projects-facet button-link active" + data-key="lang" + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - <SearchableFilterOption - optionKey="lang" - /> - </span> - <span - className="facet-stat" - > - 4 - </span> - </button> - <button - aria-checked={true} - aria-label="projects.facets.label_text_x.projects.facets.tags.sonar" - className="facet search-navigator-facet projects-facet button-link active" - data-key="sonar" + <span + className="facet-name" + > + <SearchableFilterOption + optionKey="lang" + /> + </span> + <span + className="facet-stat" + > + 4 + </span> + </button> + </li> + <li + className="active" key="sonar" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" - > - <SearchableFilterOption - optionKey="sonar" - /> - </span> - <span - className="facet-stat" + <button + aria-checked={true} + aria-label="projects.facets.label_text_x.projects.facets.tags.sonar" + className="facet search-navigator-facet projects-facet button-link active" + data-key="sonar" + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 3 - </span> - </button> - <button - aria-checked={false} - aria-label="projects.facets.label_text_x.projects.facets.tags.csharp" - className="facet search-navigator-facet projects-facet button-link" - data-key="csharp" + <span + className="facet-name" + > + <SearchableFilterOption + optionKey="sonar" + /> + </span> + <span + className="facet-stat" + > + 3 + </span> + </button> + </li> + <li + className="" key="csharp" - onClick={[Function]} - role="checkbox" - tabIndex={0} - type="button" > - <span - className="facet-name" - > - <SearchableFilterOption - optionKey="csharp" - /> - </span> - <span - className="facet-stat" + <button + aria-checked={false} + aria-label="projects.facets.label_text_x.projects.facets.tags.csharp" + className="facet search-navigator-facet projects-facet button-link" + data-key="csharp" + onClick={[Function]} + role="checkbox" + tabIndex={0} + type="button" > - 1 - </span> - </button> - </div> + <span + className="facet-name" + > + <SearchableFilterOption + optionKey="csharp" + /> + </span> + <span + className="facet-stat" + > + 1 + </span> + </button> + </li> + </ul> <SearchableFilterFooter isLoading={false} onInputChange={[Function]} diff --git a/server/sonar-web/src/main/js/apps/projects/styles.css b/server/sonar-web/src/main/js/apps/projects/styles.css index 6e226a562ed..018d8eb99bb 100644 --- a/server/sonar-web/src/main/js/apps/projects/styles.css +++ b/server/sonar-web/src/main/js/apps/projects/styles.css @@ -82,15 +82,107 @@ transition: width 0.3s ease; } -.search-navigator-facet.active .projects-facet-bar-inner, -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet - .projects-facet-bar-inner { - background-color: var(--blue); -} - .projects-empty-list { padding: calc(4 * var(--gridSize)) 0; text-align: center; } + +/*** + Custom filter highlights. + Projects filters are special, as some elements allow the selection of "everything + worse than" filters (e.g., "Rating B or worse"). We still select a single element, + but we want to give a visual indication that we selected multiple fitlers. + That's where the following selectors come in, which extend and override styles + from ../../components/search-navigator.css +***/ + +/* + Completely remove the border of the child facet. Handle them at the parent + <li> level. +*/ +.search-navigator-facet-worse-than-highlight .search-navigator-facet { + border: 0 !important; +} + +.search-navigator-facet-worse-than-highlight { + padding: 1px 0; + border-width: 0 1px; + border-color: transparent; + border-style: solid; + box-sizing: border-box; +} + +/* + When: + - Being hovered + - Or, being a sibling of something hovered + - Or, being active + - Or, being a sibling of something active + show the left and right borders. +*/ +.search-navigator-facet-worse-than-highlight:hover, +.search-navigator-facet-worse-than-highlight:hover ~ .search-navigator-facet-worse-than-highlight, +.search-navigator-facet-worse-than-highlight.active, +.search-navigator-facet-worse-than-highlight.active ~ .search-navigator-facet-worse-than-highlight { + border-left-color: var(--blue); + border-right-color: var(--blue); +} + +/* + When: + - Being hovered + - Or, being active + show the top border, and remove the top padding. +*/ +.search-navigator-facet-worse-than-highlight:hover, +.search-navigator-facet-worse-than-highlight.active { + border-top: 1px solid var(--blue) !important; + border-top-left-radius: 2px; + border-top-right-radius: 2px; + padding-top: 0 !important; +} + +/* + When: + - Being hovered AND the last element of the highlightable group + - Or, being the last element of the highlightable group AND a sibling of something hovered + - Or, being active AND the last element of the highlightable group + - Or, being the last element of the highlightable group AND a sibling of something active + show the bottom border, and remove the bottom padding. +*/ +.search-navigator-facet-worse-than-highlight.last:hover, +.search-navigator-facet-worse-than-highlight:hover + ~ .search-navigator-facet-worse-than-highlight.last, +.search-navigator-facet-worse-than-highlight.active.last, +.search-navigator-facet-worse-than-highlight.active + ~ .search-navigator-facet-worse-than-highlight.last { + border-bottom: 1px solid var(--blue) !important; + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; + padding-bottom: 0 !important; +} + +/* + When: + - Being active + - Or, being a sibling of something active + show a light blue background color. +*/ +.search-navigator-facet-worse-than-highlight.active, +.search-navigator-facet-worse-than-highlight.active ~ .search-navigator-facet-worse-than-highlight { + background-color: var(--veryLightBlue); +} + +/* + When: + - Being hovered AND a sibling of something active + - Or, being a sibling of something hovered AND a sibling of something active + show a darker blue background color. +*/ +.search-navigator-facet-worse-than-highlight.active + ~ .search-navigator-facet-worse-than-highlight:hover, +.search-navigator-facet-worse-than-highlight.active + ~ .search-navigator-facet-worse-than-highlight:hover + ~ .search-navigator-facet-worse-than-highlight { + background-color: #a1cde8; +} diff --git a/server/sonar-web/src/main/js/components/search-navigator.css b/server/sonar-web/src/main/js/components/search-navigator.css index 074aa308d5c..d54c4cf9285 100644 --- a/server/sonar-web/src/main/js/components/search-navigator.css +++ b/server/sonar-web/src/main/js/components/search-navigator.css @@ -218,96 +218,6 @@ button.search-navigator-facet:focus, margin-right: 10%; } -.search-navigator-facet-highlight-under-container { - margin-bottom: 1px; -} - -.search-navigator-facet-highlight-under-container .search-navigator-facet { - margin-bottom: 0; -} - -.search-navigator-facet-highlight-under-container .search-navigator-facet:hover, -.search-navigator-facet-highlight-under-container .search-navigator-facet.active { - border-bottom: none; - padding-bottom: 1px; - border-radius: 2px 2px 0 0; -} - -.search-navigator-facet-highlight-under-container - .search-navigator-facet:hover - ~ .search-navigator-facet, -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet { - border-top: none; - border-bottom: none; - border-left-color: var(--blue); - border-right-color: var(--blue); - border-radius: 0; -} - -.search-navigator-facet-highlight-under-container - .search-navigator-facet:hover - ~ .search-navigator-facet:last-of-type, -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet:last-of-type { - border-bottom: 1px solid var(--blue); - border-radius: 0 0 2px 2px; -} - -.search-navigator-facet-highlight-under-container .search-navigator-facet:hover:last-of-type, -.search-navigator-facet-highlight-under-container .search-navigator-facet.active:last-of-type { - border-bottom: 1px solid var(--blue); - border-radius: 2px; -} - -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet { - background-color: var(--veryLightBlue); - text-decoration: none; -} - -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet - .facet-toggle { - display: inline; -} - -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet:hover, -.search-navigator-facet-highlight-under-container - .search-navigator-facet:hover - ~ .search-navigator-facet.active { - border-top: 1px solid var(--blue); -} - -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet:hover, -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet:hover - ~ .search-navigator-facet { - background-color: #a1cde8; - text-decoration: none; -} - -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet:hover - .facet-toggle, -.search-navigator-facet-highlight-under-container - .search-navigator-facet.active - ~ .search-navigator-facet:hover - ~ .search-navigator-facet - .facet-toggle { - display: inline; -} - .search-navigator-facet-header { display: block; flex-shrink: 0; @@ -379,7 +289,6 @@ button.search-navigator-facet:focus, padding: 0 10px 10px; color: var(--baseFontColor); font-size: var(--smallFontSize); - white-space: nowrap; } .search-navigator-facet-footer { diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index eb7a42fcb26..e8b7b629d87 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1091,6 +1091,7 @@ projects.facets.duplication.label.2=Click to filter projects with more than 3% d projects.facets.duplication.label.3=Click to filter projects with more than 5% duplication projects.facets.duplication.label.4=Click to filter projects with more than 10% duplication projects.facets.duplication.label.5=Click to filter projects with more than 20% duplication +projects.facets.no_available_filters_clear_others=No available filters. Clear other filters to see options. projects.sort.disabled=Disabled because sorting cannot affect the displayed result with the current project selection. projects.sort.analysis_date=by last analysis date (oldest first) projects.sort.-analysis_date=by last analysis date (latest first) |