PanelMenu: Fixes panel submenu not being accessible for panels close to the right edge of the screen (#28666)

* Dropdowns: Trying to fix dropdown menus

* Dropdowns: Trying to fix dropdown menus

* removed now unnessary wrapper ref

* Upodates

* Remove export
This commit is contained in:
Torkel Ödegaard
2020-10-29 19:48:54 +01:00
committed by GitHub
parent 6dbf1f830a
commit 5a83fc574a
5 changed files with 68 additions and 24 deletions

View File

@@ -44,7 +44,7 @@ export const DashboardLinks: FC<Props> = ({ dashboard, links }) => {
const linkElement = (
<a
className="gf-form-label"
className="gf-form-label gf-form-label--dashlink"
href={sanitizeUrl(linkInfo.href)}
target={link.targetBlank ? '_blank' : '_self'}
aria-label={selectors.components.DashboardLinks.link}

View File

@@ -19,7 +19,6 @@ interface State {
export class DashboardLinksDashboard extends PureComponent<Props, State> {
state: State = { resolvedLinks: [] };
wrapperRef = createRef<HTMLDivElement>();
listItemRef = createRef<HTMLUListElement>();
componentDidMount() {
@@ -45,7 +44,7 @@ export class DashboardLinksDashboard extends PureComponent<Props, State> {
const { link } = this.props;
return (
<div className="gf-form" key={key} aria-label={selector} ref={this.wrapperRef}>
<div className="gf-form" key={key} aria-label={selector}>
{link.tooltip && <Tooltip content={link.tooltip}>{linkElement}</Tooltip>}
{!link.tooltip && <>{linkElement}</>}
</div>
@@ -62,7 +61,7 @@ export class DashboardLinksDashboard extends PureComponent<Props, State> {
resolvedLinks.map((resolvedLink, index) => {
const linkElement = (
<a
className="gf-form-label"
className="gf-form-label gf-form-label--dashlink"
href={resolvedLink.url}
target={link.targetBlank ? '_blank' : '_self'}
aria-label={selectors.components.DashboardLinks.link}
@@ -81,32 +80,26 @@ export class DashboardLinksDashboard extends PureComponent<Props, State> {
);
};
getDropdownLocationCssClass = (): string => {
const [pullLeftCssClass, pullRightCssClass] = ['pull-left', 'pull-right'];
const wrapper = this.wrapperRef.current;
const list = this.listItemRef.current;
if (!wrapper || !list) {
return pullRightCssClass;
}
return wrapper.offsetLeft > list.offsetWidth - wrapper.offsetWidth ? pullRightCssClass : pullLeftCssClass;
};
renderDropdown = () => {
renderDropdown() {
const { link, linkInfo } = this.props;
const { resolvedLinks } = this.state;
const linkElement = (
<>
<a
className="gf-form-label pointer"
className="gf-form-label gf-form-label--dashlink"
onClick={this.searchForDashboards}
data-placement="bottom"
data-toggle="dropdown"
>
<Icon name="bars" />
<Icon name="bars" style={{ marginRight: '4px' }} />
<span>{linkInfo.title}</span>
</a>
<ul className={'dropdown-menu ' + this.getDropdownLocationCssClass()} role="menu" ref={this.listItemRef}>
<ul
className={`dropdown-menu ${getDropdownLocationCssClass(this.listItemRef.current)}`}
role="menu"
ref={this.listItemRef}
>
{resolvedLinks.length > 0 &&
resolvedLinks.map((resolvedLink, index) => {
return (
@@ -126,7 +119,7 @@ export class DashboardLinksDashboard extends PureComponent<Props, State> {
);
return this.renderElement(linkElement, 'dashlinks-dropdown', selectors.components.DashboardLinks.dropDown);
};
}
render() {
if (this.props.link.asDropdown) {
@@ -174,3 +167,22 @@ export function resolveLinks(
return { id, title, url };
});
}
function getDropdownLocationCssClass(element: HTMLElement | null) {
if (!element) {
return 'invisible';
}
const wrapperPos = element.parentElement!.getBoundingClientRect();
const pos = element.getBoundingClientRect();
if (pos.width === 0) {
return 'invisible';
}
if (wrapperPos.left + pos.width + 10 > window.innerWidth) {
return 'pull-left';
} else {
return 'pull-right';
}
}