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:
@@ -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),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user