const more = props.more[qualifier];
renderedComponents.push(
- <ul className="menu" key={`header-${qualifier}`}>
- <li className="menu-header" role="presentation">
+ <>
+ <h2 className="menu-header no-margin" id={translate('qualifiers', qualifier)}>
{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>
+ </h2>
+ <ul
+ className="menu"
+ key={`header-${qualifier}`}
+ aria-labelledby={translate('qualifiers', qualifier)}
+ >
+ {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>
+ </>
);
}
});
exports[`renders "Show More" link 1`] = `
<div>
+ <h2
+ className="menu-header no-margin"
+ id="qualifiers.TRK"
+ >
+ qualifiers.TRK
+ </h2>
<ul
+ aria-labelledby="qualifiers.TRK"
className="menu"
key="header-TRK"
>
- <li
- className="menu-header"
- role="presentation"
- >
- qualifiers.TRK
- </li>
<span
key="foo"
>
exports[`renders different components and dividers between them 1`] = `
<div>
+ <h2
+ className="menu-header no-margin"
+ id="qualifiers.FIL"
+ >
+ qualifiers.FIL
+ </h2>
<ul
+ aria-labelledby="qualifiers.FIL"
className="menu"
key="header-FIL"
>
- <li
- className="menu-header"
- role="presentation"
- >
- qualifiers.FIL
- </li>
<span
key="zux"
>
zux
</span>
</ul>
+ <h2
+ className="menu-header no-margin"
+ id="qualifiers.TRK"
+ >
+ qualifiers.TRK
+ </h2>
<ul
+ aria-labelledby="qualifiers.TRK"
className="menu"
key="header-TRK"
>
- <li
- className="menu-header"
- role="presentation"
- >
- qualifiers.TRK
- </li>
<span
key="foo"
>
padding-bottom: 12px;
}
-.menu + .menu {
+.menu + .menu,
+.menu + .menu-header {
border-top: 1px solid var(--barBorderColor);
}
.menu-header {
padding: var(--gridSize);
+ margin: -8px;
font-size: 12px;
color: var(--neutral600);
white-space: nowrap;
+ line-height: unset;
+}
+
+.menu-header + ul {
+ padding-top: 8px;
+}
+
+.menu-header.no-margin + ul {
+ padding-top: 0;
+}
+
+.menu-header.no-margin {
+ margin: 0;
}
-.menu-header:first-child,
.divider + .menu-header {
padding-top: calc(var(--gridSize) - 5px);
}
<Dropdown
className="display-inline-block"
overlay={
- <ul className="menu">
- <li className="menu-header">{translate('coding_rules.filter_similar_rules')}</li>
- <li>
- <a
- data-test="coding-rules__similar-language"
- href="#"
- onClick={this.handleLanguageClick}
- >
- {rule.langName}
- </a>
- </li>
-
- <li>
- <a
- className="display-flex-center"
- data-test="coding-rules__similar-type"
- href="#"
- onClick={this.handleTypeClick}
- >
- <IssueTypeIcon query={rule.type} />
- <span className="little-spacer-left">{translate('issue.type', rule.type)}</span>
- </a>
- </li>
-
- {severity && (
+ <>
+ <h2 className="menu-header" id="filter-similar-rules">
+ {translate('coding_rules.filter_similar_rules')}
+ </h2>
+ <ul className="menu" aria-labelledby="filter-similar-rules">
<li>
<a
- data-test="coding-rules__similar-severity"
+ data-test="coding-rules__similar-language"
href="#"
- onClick={this.handleSeverityClick}
+ onClick={this.handleLanguageClick}
>
- <SeverityHelper className="display-flex-center" severity={rule.severity} />
+ {rule.langName}
</a>
</li>
- )}
- {allTags.length > 0 && <li className="divider" />}
- {allTags.map((tag) => (
- <li key={tag}>
+ <li>
<a
- data-tag={tag}
- data-test="coding-rules__similar-tag"
+ className="display-flex-center"
+ data-test="coding-rules__similar-type"
href="#"
- onClick={this.handleTagClick}
+ onClick={this.handleTypeClick}
>
- <TagsIcon className="little-spacer-right text-middle" />
- <span className="text-middle">{tag}</span>
+ <IssueTypeIcon query={rule.type} />
+ <span className="little-spacer-left">{translate('issue.type', rule.type)}</span>
</a>
</li>
- ))}
- </ul>
+
+ {severity && (
+ <li>
+ <a
+ data-test="coding-rules__similar-severity"
+ href="#"
+ onClick={this.handleSeverityClick}
+ >
+ <SeverityHelper className="display-flex-center" severity={rule.severity} />
+ </a>
+ </li>
+ )}
+
+ {allTags.length > 0 && <li className="divider" />}
+ {allTags.map((tag) => (
+ <li key={tag}>
+ <a
+ data-tag={tag}
+ data-test="coding-rules__similar-tag"
+ href="#"
+ onClick={this.handleTagClick}
+ >
+ <TagsIcon className="little-spacer-right text-middle" />
+ <span className="text-middle">{tag}</span>
+ </a>
+ </li>
+ ))}
+ </ul>
+ </>
}
>
<a
<Dropdown
className="display-inline-block"
overlay={
- <ul
- className="menu"
- >
- <li
+ <React.Fragment>
+ <h2
className="menu-header"
+ id="filter-similar-rules"
>
coding_rules.filter_similar_rules
- </li>
- <li>
- <a
- data-test="coding-rules__similar-language"
- href="#"
- onClick={[Function]}
- >
- JavaScript
- </a>
- </li>
- <li>
- <a
- className="display-flex-center"
- data-test="coding-rules__similar-type"
- href="#"
- onClick={[Function]}
- >
- <IssueTypeIcon
- query="CODE_SMELL"
- />
- <span
- className="little-spacer-left"
+ </h2>
+ <ul
+ aria-labelledby="filter-similar-rules"
+ className="menu"
+ >
+ <li>
+ <a
+ data-test="coding-rules__similar-language"
+ href="#"
+ onClick={[Function]}
>
- issue.type.CODE_SMELL
- </span>
- </a>
- </li>
- <li>
- <a
- data-test="coding-rules__similar-severity"
- href="#"
- onClick={[Function]}
- >
- <SeverityHelper
+ JavaScript
+ </a>
+ </li>
+ <li>
+ <a
className="display-flex-center"
- severity="MAJOR"
- />
- </a>
- </li>
- <li
- className="divider"
- />
- <li>
- <a
- data-tag="x"
- data-test="coding-rules__similar-tag"
- href="#"
- onClick={[Function]}
- >
- <TagsIcon
- className="little-spacer-right text-middle"
- />
- <span
- className="text-middle"
+ data-test="coding-rules__similar-type"
+ href="#"
+ onClick={[Function]}
+ >
+ <IssueTypeIcon
+ query="CODE_SMELL"
+ />
+ <span
+ className="little-spacer-left"
+ >
+ issue.type.CODE_SMELL
+ </span>
+ </a>
+ </li>
+ <li>
+ <a
+ data-test="coding-rules__similar-severity"
+ href="#"
+ onClick={[Function]}
+ >
+ <SeverityHelper
+ className="display-flex-center"
+ severity="MAJOR"
+ />
+ </a>
+ </li>
+ <li
+ className="divider"
+ />
+ <li>
+ <a
+ data-tag="x"
+ data-test="coding-rules__similar-tag"
+ href="#"
+ onClick={[Function]}
>
- x
- </span>
- </a>
- </li>
- <li>
- <a
- data-tag="a"
- data-test="coding-rules__similar-tag"
- href="#"
- onClick={[Function]}
- >
- <TagsIcon
- className="little-spacer-right text-middle"
- />
- <span
- className="text-middle"
+ <TagsIcon
+ className="little-spacer-right text-middle"
+ />
+ <span
+ className="text-middle"
+ >
+ x
+ </span>
+ </a>
+ </li>
+ <li>
+ <a
+ data-tag="a"
+ data-test="coding-rules__similar-tag"
+ href="#"
+ onClick={[Function]}
>
- a
- </span>
- </a>
- </li>
- <li>
- <a
- data-tag="b"
- data-test="coding-rules__similar-tag"
- href="#"
- onClick={[Function]}
- >
- <TagsIcon
- className="little-spacer-right text-middle"
- />
- <span
- className="text-middle"
+ <TagsIcon
+ className="little-spacer-right text-middle"
+ />
+ <span
+ className="text-middle"
+ >
+ a
+ </span>
+ </a>
+ </li>
+ <li>
+ <a
+ data-tag="b"
+ data-test="coding-rules__similar-tag"
+ href="#"
+ onClick={[Function]}
>
- b
- </span>
- </a>
- </li>
- </ul>
+ <TagsIcon
+ className="little-spacer-right text-middle"
+ />
+ <span
+ className="text-middle"
+ >
+ b
+ </span>
+ </a>
+ </li>
+ </ul>
+ </React.Fragment>
}
>
<a
}
};
- renderTitle(text: string) {
+ renderTitle(text: string, labelId: string) {
return (
- <li role="presentation" className="menu-header">
+ <h2 className="menu-header" id={labelId}>
{text}
- </li>
+ </h2>
);
}
return null;
}
return (
- <ul className="menu abs-width-240">
- {this.renderTitle(translate('docs.suggestion'))}
- {suggestions.map((suggestion, i) => (
- <li key={suggestion.link}>
- <DocLink
- innerRef={i === 0 ? this.focusFirstItem : undefined}
- onClick={this.props.onClose}
- to={suggestion.link}
- >
- {suggestion.text}
- </DocLink>
- </li>
- ))}
- </ul>
+ <>
+ {this.renderTitle(translate('docs.suggestion'), 'suggestion')}
+ <ul className="menu abs-width-240" aria-labelledby="suggestion">
+ {suggestions.map((suggestion, i) => (
+ <li key={suggestion.link}>
+ <DocLink
+ innerRef={i === 0 ? this.focusFirstItem : undefined}
+ onClick={this.props.onClose}
+ to={suggestion.link}
+ >
+ {suggestion.text}
+ </DocLink>
+ </li>
+ ))}
+ </ul>
+ </>
);
};
</Link>
</li>
</ul>
- <ul className="menu abs-width-240">
- {this.renderTitle(translate('docs.stay_connected'))}
+ {this.renderTitle(translate('docs.stay_connected'), 'stay_connected')}
+ <ul className="menu abs-width-240" aria-labelledby="stay_connected">
<li>
{this.renderIconLink(
'https://www.sonarqube.org/whats-new/?referrer=sonarqube',