mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Navigation: Expand active page hierarchy and scroll into center if not visible (#76949)
* expand page hierarchy and scroll into center if not visible * remove unnecessary id
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import React from 'react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { useLocalStorage } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2, NavModelItem, toIconName } from '@grafana/data';
|
||||
@@ -24,18 +24,37 @@ export function MegaMenuItem({ link, activeItem, level = 0, onClick }: Props) {
|
||||
const FeatureHighlightWrapper = link.highlightText ? FeatureHighlight : React.Fragment;
|
||||
const hasActiveChild = hasChildMatch(link, activeItem);
|
||||
const isActive = link === activeItem || (level === MAX_DEPTH && hasActiveChild);
|
||||
const [sectionExpanded, setSectionExpanded] =
|
||||
useLocalStorage(`grafana.navigation.expanded[${link.text}]`, false) ?? Boolean(hasActiveChild);
|
||||
const [sectionExpanded, setSectionExpanded] = useLocalStorage(
|
||||
`grafana.navigation.expanded[${link.text}]`,
|
||||
Boolean(hasActiveChild)
|
||||
);
|
||||
const showExpandButton = level < MAX_DEPTH && Boolean(linkHasChildren(link) || link.emptyMessage);
|
||||
const item = useRef<HTMLLIElement>(null);
|
||||
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
// expand parent sections if child is active
|
||||
useEffect(() => {
|
||||
if (hasActiveChild) {
|
||||
setSectionExpanded(true);
|
||||
}
|
||||
}, [hasActiveChild, setSectionExpanded]);
|
||||
|
||||
// scroll active element into center if it's offscreen
|
||||
useEffect(() => {
|
||||
if (isActive && item.current && isElementOffscreen(item.current)) {
|
||||
item.current.scrollIntoView({
|
||||
block: 'center',
|
||||
});
|
||||
}
|
||||
}, [isActive]);
|
||||
|
||||
if (!link.url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<li className={styles.listItem}>
|
||||
<li ref={item} className={styles.listItem}>
|
||||
<div
|
||||
className={cx(styles.menuItem, {
|
||||
[styles.hasIcon]: Boolean(level === 0 && link.icon),
|
||||
@@ -175,3 +194,8 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
function linkHasChildren(link: NavModelItem): link is NavModelItem & { children: NavModelItem[] } {
|
||||
return Boolean(link.children && link.children.length > 0);
|
||||
}
|
||||
|
||||
function isElementOffscreen(element: HTMLElement) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
return rect.bottom < 0 || rect.top >= window.innerHeight;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user