Nav: Remove and refactor MegaMenu and its sub-components (#76614)

* refactor: remove hasActiveChild

* refactor: remove unused properties from MegeMenuItemText

* refactor: remove MegaMenuItemIcon

* refactor after code review
This commit is contained in:
Laura Benz
2023-10-17 10:34:44 +02:00
committed by GitHub
parent 99c2467db3
commit a546db4b3a
3 changed files with 9 additions and 63 deletions
@@ -2,13 +2,12 @@ import { css, cx } from '@emotion/css';
import React from 'react';
import { useLocalStorage } from 'react-use';
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
import { GrafanaTheme2, NavModelItem, toIconName } from '@grafana/data';
import { Button, Icon, useStyles2, Text } from '@grafana/ui';
import { Indent } from '../../Indent/Indent';
import { FeatureHighlight } from './FeatureHighlight';
import { MegaMenuItemIcon } from './MegaMenuItemIcon';
import { MegaMenuItemText } from './MegaMenuItemText';
import { hasChildMatch } from './utils';
@@ -46,11 +45,12 @@ export function MegaMenuItem({ link, activeItem, level = 0, onClick }: Props) {
<div
className={cx(styles.labelWrapper, {
[styles.isActive]: isActive,
[styles.hasActiveChild]: hasActiveChild,
})}
>
<FeatureHighlightWrapper>
<div className={styles.iconWrapper}>{level === 0 && <MegaMenuItemIcon link={link} />}</div>
<div className={styles.iconWrapper}>
{level === 0 && link.icon && <Icon name={toIconName(link.icon) ?? 'link'} size="xl" />}
</div>
</FeatureHighlightWrapper>
<Indent level={Math.max(0, level - 1)} spacing={2} />
<Text truncate>{link.text}</Text>
@@ -143,9 +143,6 @@ const getStyles = (theme: GrafanaTheme2) => ({
backgroundImage: theme.colors.gradients.brandVertical,
},
}),
hasActiveChild: css({
color: theme.colors.text.primary,
}),
});
function linkHasChildren(link: NavModelItem): link is NavModelItem & { children: NavModelItem[] } {
@@ -1,38 +0,0 @@
import { css, cx } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
import { Icon, toIconName, useTheme2 } from '@grafana/ui';
import { Branding } from '../../Branding/Branding';
interface NavBarItemIconProps {
link: NavModelItem;
}
export function MegaMenuItemIcon({ link }: NavBarItemIconProps) {
const theme = useTheme2();
const styles = getStyles(theme);
if (link.icon === 'grafana') {
return <Branding.MenuLogo className={styles.img} />;
} else if (link.icon) {
const iconName = toIconName(link.icon);
return <Icon name={iconName ?? 'link'} size="xl" />;
} else {
// consumer of NavBarItemIcon gives enclosing element an appropriate label
return <img className={cx(styles.img, link.roundIcon && styles.round)} src={link.img} alt="" />;
}
}
function getStyles(theme: GrafanaTheme2) {
return {
img: css({
height: theme.spacing(3),
width: theme.spacing(3),
}),
round: css({
borderRadius: theme.shape.radius.circle,
}),
};
}
@@ -3,26 +3,22 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Icon, IconName, Link, useTheme2 } from '@grafana/ui';
import { Icon, Link, useTheme2 } from '@grafana/ui';
export interface Props {
children: React.ReactNode;
icon?: IconName;
isActive?: boolean;
isChild?: boolean;
onClick?: () => void;
target?: HTMLAnchorElement['target'];
url?: string;
}
export function MegaMenuItemText({ children, icon, isActive, isChild, onClick, target, url }: Props) {
export function MegaMenuItemText({ children, isActive, onClick, target, url }: Props) {
const theme = useTheme2();
const styles = getStyles(theme, isActive, isChild);
const styles = getStyles(theme, isActive);
const linkContent = (
<div className={styles.linkContent}>
{icon && <Icon data-testid="dropdown-child-icon" name={icon} />}
{children}
{target === '_blank' && (
@@ -71,7 +67,7 @@ export function MegaMenuItemText({ children, icon, isActive, isChild, onClick, t
MegaMenuItemText.displayName = 'MegaMenuItemText';
const getStyles = (theme: GrafanaTheme2, isActive: Props['isActive'], isChild: Props['isActive']) => ({
const getStyles = (theme: GrafanaTheme2, isActive: Props['isActive']) => ({
button: css({
backgroundColor: 'unset',
borderStyle: 'unset',
@@ -91,15 +87,9 @@ const getStyles = (theme: GrafanaTheme2, isActive: Props['isActive'], isChild: P
boxSizing: 'border-box',
position: 'relative',
color: isActive ? theme.colors.text.primary : theme.colors.text.secondary,
padding: theme.spacing(1, 1, 1, isChild ? 5 : 0),
...(isChild && {
borderRadius: theme.shape.radius.default,
}),
padding: theme.spacing(1, 1, 1, 0),
width: '100%',
'&:hover, &:focus-visible': {
...(isChild && {
background: theme.colors.emphasize(theme.colors.background.primary, 0.03),
}),
textDecoration: 'underline',
color: theme.colors.text.primary,
},
@@ -127,8 +117,5 @@ const getStyles = (theme: GrafanaTheme2, isActive: Props['isActive'], isChild: P
position: 'relative',
display: 'flex',
width: '100%',
...(isChild && {
padding: theme.spacing(0, 2),
}),
}),
});