The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/public/app/core/components/NavBar/NavBarMenuItem.tsx

154 lines
3.8 KiB

import { css, cx } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Icon, IconName, Link, useTheme2 } from '@grafana/ui';
export interface Props {
icon?: IconName;
isActive?: boolean;
isDivider?: boolean;
onClick?: () => void;
styleOverrides?: string;
target?: HTMLAnchorElement['target'];
text: React.ReactNode;
url?: string;
Navigation: Implement Keyboard Navigation (#41618) * Navigation: Start creating new NavBarMenu component * Navigation: Apply new NavBarMenu to NavBarNext * Navigation: Remove everything to do with .sidemenu-open--xs * Navigation: Ensure search is passed to NavBarMenu * Navigation: Standardise NavBarMenuItem * This extra check isn't needed anymore * Navigation: Refactor <li> out of NavBarMenu * Navigation: Combine NavBarMenuItem with DropdownChild * use spread syntax since performance shouldn't be a concern for such small arrays * Improve active item logic * Ensure unique keys * Remove this duplicate code * Add unit tests for getActiveItem * Add tests for NavBarMenu * Rename mobileMenuOpen -> menuOpen in NavBarNext (since it can be used for mobile menu or megamenu) * just use index to key the items * Use exact versions of @react-aria packages * Navigation: Make the dropdown header a NavBarMenuItem * Navigation: Stop using dropdown-menu for styles * Navigation: Add react-aria relevant packages * Navigation: Refactor NavBarDropdown to support react aria * Navigation: apply keyboard navigation to NavBar component * Navigation: UseHover hook for triggering submenu on navbar * Navigation: rename testMenu component to NavBarItemButton * WIP * some hacks * Refactor: clean up keybinding events * Navigation: render subtitle on item menu and disable it * Navigation: Adds react-aria types (#42113) * Refactor: refactor out to NavBarItemWithoutMenu * Refactor: cleaning up stuff * Refactor: comment out unused code * Chore: Removes section and uses items only * Chore: fix NavBarNext * Chore: adds tests * Refactor: minimize props api * Refactor: various refactors * Refactor: rename enableAllItems * Refactor: remove unused code * Refactor: fix clicking on menuitems * Refactor: use recommended onAction instead * Navigation: Fix a11y issues on NavBar * Navigation: Fix a11y navBar Next * Navigation: Remove unnecessary label prop, use link.text instead * Apply suggestions from code review Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> * Apply unit tests suggestions from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update react-aria/menu package to latest version and apply PR suggestion Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
4 years ago
adjustHeightForBorder?: boolean;
isMobile?: boolean;
}
Navigation: Implement Keyboard Navigation (#41618) * Navigation: Start creating new NavBarMenu component * Navigation: Apply new NavBarMenu to NavBarNext * Navigation: Remove everything to do with .sidemenu-open--xs * Navigation: Ensure search is passed to NavBarMenu * Navigation: Standardise NavBarMenuItem * This extra check isn't needed anymore * Navigation: Refactor <li> out of NavBarMenu * Navigation: Combine NavBarMenuItem with DropdownChild * use spread syntax since performance shouldn't be a concern for such small arrays * Improve active item logic * Ensure unique keys * Remove this duplicate code * Add unit tests for getActiveItem * Add tests for NavBarMenu * Rename mobileMenuOpen -> menuOpen in NavBarNext (since it can be used for mobile menu or megamenu) * just use index to key the items * Use exact versions of @react-aria packages * Navigation: Make the dropdown header a NavBarMenuItem * Navigation: Stop using dropdown-menu for styles * Navigation: Add react-aria relevant packages * Navigation: Refactor NavBarDropdown to support react aria * Navigation: apply keyboard navigation to NavBar component * Navigation: UseHover hook for triggering submenu on navbar * Navigation: rename testMenu component to NavBarItemButton * WIP * some hacks * Refactor: clean up keybinding events * Navigation: render subtitle on item menu and disable it * Navigation: Adds react-aria types (#42113) * Refactor: refactor out to NavBarItemWithoutMenu * Refactor: cleaning up stuff * Refactor: comment out unused code * Chore: Removes section and uses items only * Chore: fix NavBarNext * Chore: adds tests * Refactor: minimize props api * Refactor: various refactors * Refactor: rename enableAllItems * Refactor: remove unused code * Refactor: fix clicking on menuitems * Refactor: use recommended onAction instead * Navigation: Fix a11y issues on NavBar * Navigation: Fix a11y navBar Next * Navigation: Remove unnecessary label prop, use link.text instead * Apply suggestions from code review Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> * Apply unit tests suggestions from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update react-aria/menu package to latest version and apply PR suggestion Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
4 years ago
export function NavBarMenuItem({
icon,
isActive,
isDivider,
onClick,
styleOverrides,
target,
text,
url,
isMobile = false,
}: Props) {
const theme = useTheme2();
const styles = getStyles(theme, isActive);
const elStyle = cx(styles.element, styleOverrides);
const linkContent = (
<div className={styles.linkContent}>
{icon && <Icon data-testid="dropdown-child-icon" name={icon} />}
<div className={styles.linkText}>{text}</div>
{target === '_blank' && (
<Icon data-testid="external-link-icon" name="external-link-alt" className={styles.externalLinkIcon} />
)}
</div>
);
let element = (
<button className={elStyle} onClick={onClick} tabIndex={-1}>
{linkContent}
</button>
);
if (url) {
element =
!target && url.startsWith('/') ? (
<Link className={elStyle} href={url} target={target} onClick={onClick} tabIndex={!isMobile ? -1 : 0}>
{linkContent}
</Link>
) : (
<a href={url} target={target} className={elStyle} onClick={onClick} tabIndex={!isMobile ? -1 : 0}>
{linkContent}
</a>
);
}
Navigation: Implement Keyboard Navigation (#41618) * Navigation: Start creating new NavBarMenu component * Navigation: Apply new NavBarMenu to NavBarNext * Navigation: Remove everything to do with .sidemenu-open--xs * Navigation: Ensure search is passed to NavBarMenu * Navigation: Standardise NavBarMenuItem * This extra check isn't needed anymore * Navigation: Refactor <li> out of NavBarMenu * Navigation: Combine NavBarMenuItem with DropdownChild * use spread syntax since performance shouldn't be a concern for such small arrays * Improve active item logic * Ensure unique keys * Remove this duplicate code * Add unit tests for getActiveItem * Add tests for NavBarMenu * Rename mobileMenuOpen -> menuOpen in NavBarNext (since it can be used for mobile menu or megamenu) * just use index to key the items * Use exact versions of @react-aria packages * Navigation: Make the dropdown header a NavBarMenuItem * Navigation: Stop using dropdown-menu for styles * Navigation: Add react-aria relevant packages * Navigation: Refactor NavBarDropdown to support react aria * Navigation: apply keyboard navigation to NavBar component * Navigation: UseHover hook for triggering submenu on navbar * Navigation: rename testMenu component to NavBarItemButton * WIP * some hacks * Refactor: clean up keybinding events * Navigation: render subtitle on item menu and disable it * Navigation: Adds react-aria types (#42113) * Refactor: refactor out to NavBarItemWithoutMenu * Refactor: cleaning up stuff * Refactor: comment out unused code * Chore: Removes section and uses items only * Chore: fix NavBarNext * Chore: adds tests * Refactor: minimize props api * Refactor: various refactors * Refactor: rename enableAllItems * Refactor: remove unused code * Refactor: fix clicking on menuitems * Refactor: use recommended onAction instead * Navigation: Fix a11y issues on NavBar * Navigation: Fix a11y navBar Next * Navigation: Remove unnecessary label prop, use link.text instead * Apply suggestions from code review Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> * Apply unit tests suggestions from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update react-aria/menu package to latest version and apply PR suggestion Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
4 years ago
if (isMobile) {
return isDivider ? (
<div data-testid="dropdown-child-divider" className={styles.divider} tabIndex={-1} aria-disabled />
Navigation: Implement Keyboard Navigation (#41618) * Navigation: Start creating new NavBarMenu component * Navigation: Apply new NavBarMenu to NavBarNext * Navigation: Remove everything to do with .sidemenu-open--xs * Navigation: Ensure search is passed to NavBarMenu * Navigation: Standardise NavBarMenuItem * This extra check isn't needed anymore * Navigation: Refactor <li> out of NavBarMenu * Navigation: Combine NavBarMenuItem with DropdownChild * use spread syntax since performance shouldn't be a concern for such small arrays * Improve active item logic * Ensure unique keys * Remove this duplicate code * Add unit tests for getActiveItem * Add tests for NavBarMenu * Rename mobileMenuOpen -> menuOpen in NavBarNext (since it can be used for mobile menu or megamenu) * just use index to key the items * Use exact versions of @react-aria packages * Navigation: Make the dropdown header a NavBarMenuItem * Navigation: Stop using dropdown-menu for styles * Navigation: Add react-aria relevant packages * Navigation: Refactor NavBarDropdown to support react aria * Navigation: apply keyboard navigation to NavBar component * Navigation: UseHover hook for triggering submenu on navbar * Navigation: rename testMenu component to NavBarItemButton * WIP * some hacks * Refactor: clean up keybinding events * Navigation: render subtitle on item menu and disable it * Navigation: Adds react-aria types (#42113) * Refactor: refactor out to NavBarItemWithoutMenu * Refactor: cleaning up stuff * Refactor: comment out unused code * Chore: Removes section and uses items only * Chore: fix NavBarNext * Chore: adds tests * Refactor: minimize props api * Refactor: various refactors * Refactor: rename enableAllItems * Refactor: remove unused code * Refactor: fix clicking on menuitems * Refactor: use recommended onAction instead * Navigation: Fix a11y issues on NavBar * Navigation: Fix a11y navBar Next * Navigation: Remove unnecessary label prop, use link.text instead * Apply suggestions from code review Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> * Apply unit tests suggestions from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update react-aria/menu package to latest version and apply PR suggestion Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
4 years ago
) : (
<li className={styles.listItem}>{element}</li>
Navigation: Implement Keyboard Navigation (#41618) * Navigation: Start creating new NavBarMenu component * Navigation: Apply new NavBarMenu to NavBarNext * Navigation: Remove everything to do with .sidemenu-open--xs * Navigation: Ensure search is passed to NavBarMenu * Navigation: Standardise NavBarMenuItem * This extra check isn't needed anymore * Navigation: Refactor <li> out of NavBarMenu * Navigation: Combine NavBarMenuItem with DropdownChild * use spread syntax since performance shouldn't be a concern for such small arrays * Improve active item logic * Ensure unique keys * Remove this duplicate code * Add unit tests for getActiveItem * Add tests for NavBarMenu * Rename mobileMenuOpen -> menuOpen in NavBarNext (since it can be used for mobile menu or megamenu) * just use index to key the items * Use exact versions of @react-aria packages * Navigation: Make the dropdown header a NavBarMenuItem * Navigation: Stop using dropdown-menu for styles * Navigation: Add react-aria relevant packages * Navigation: Refactor NavBarDropdown to support react aria * Navigation: apply keyboard navigation to NavBar component * Navigation: UseHover hook for triggering submenu on navbar * Navigation: rename testMenu component to NavBarItemButton * WIP * some hacks * Refactor: clean up keybinding events * Navigation: render subtitle on item menu and disable it * Navigation: Adds react-aria types (#42113) * Refactor: refactor out to NavBarItemWithoutMenu * Refactor: cleaning up stuff * Refactor: comment out unused code * Chore: Removes section and uses items only * Chore: fix NavBarNext * Chore: adds tests * Refactor: minimize props api * Refactor: various refactors * Refactor: rename enableAllItems * Refactor: remove unused code * Refactor: fix clicking on menuitems * Refactor: use recommended onAction instead * Navigation: Fix a11y issues on NavBar * Navigation: Fix a11y navBar Next * Navigation: Remove unnecessary label prop, use link.text instead * Apply suggestions from code review Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> * Apply unit tests suggestions from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update react-aria/menu package to latest version and apply PR suggestion Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
4 years ago
);
}
Navigation: Implement Keyboard Navigation (#41618) * Navigation: Start creating new NavBarMenu component * Navigation: Apply new NavBarMenu to NavBarNext * Navigation: Remove everything to do with .sidemenu-open--xs * Navigation: Ensure search is passed to NavBarMenu * Navigation: Standardise NavBarMenuItem * This extra check isn't needed anymore * Navigation: Refactor <li> out of NavBarMenu * Navigation: Combine NavBarMenuItem with DropdownChild * use spread syntax since performance shouldn't be a concern for such small arrays * Improve active item logic * Ensure unique keys * Remove this duplicate code * Add unit tests for getActiveItem * Add tests for NavBarMenu * Rename mobileMenuOpen -> menuOpen in NavBarNext (since it can be used for mobile menu or megamenu) * just use index to key the items * Use exact versions of @react-aria packages * Navigation: Make the dropdown header a NavBarMenuItem * Navigation: Stop using dropdown-menu for styles * Navigation: Add react-aria relevant packages * Navigation: Refactor NavBarDropdown to support react aria * Navigation: apply keyboard navigation to NavBar component * Navigation: UseHover hook for triggering submenu on navbar * Navigation: rename testMenu component to NavBarItemButton * WIP * some hacks * Refactor: clean up keybinding events * Navigation: render subtitle on item menu and disable it * Navigation: Adds react-aria types (#42113) * Refactor: refactor out to NavBarItemWithoutMenu * Refactor: cleaning up stuff * Refactor: comment out unused code * Chore: Removes section and uses items only * Chore: fix NavBarNext * Chore: adds tests * Refactor: minimize props api * Refactor: various refactors * Refactor: rename enableAllItems * Refactor: remove unused code * Refactor: fix clicking on menuitems * Refactor: use recommended onAction instead * Navigation: Fix a11y issues on NavBar * Navigation: Fix a11y navBar Next * Navigation: Remove unnecessary label prop, use link.text instead * Apply suggestions from code review Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> * Apply unit tests suggestions from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update react-aria/menu package to latest version and apply PR suggestion Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
4 years ago
return isDivider ? (
<div data-testid="dropdown-child-divider" className={styles.divider} tabIndex={-1} aria-disabled />
) : (
<div style={{ position: 'relative' }}>{element}</div>
Navigation: Implement Keyboard Navigation (#41618) * Navigation: Start creating new NavBarMenu component * Navigation: Apply new NavBarMenu to NavBarNext * Navigation: Remove everything to do with .sidemenu-open--xs * Navigation: Ensure search is passed to NavBarMenu * Navigation: Standardise NavBarMenuItem * This extra check isn't needed anymore * Navigation: Refactor <li> out of NavBarMenu * Navigation: Combine NavBarMenuItem with DropdownChild * use spread syntax since performance shouldn't be a concern for such small arrays * Improve active item logic * Ensure unique keys * Remove this duplicate code * Add unit tests for getActiveItem * Add tests for NavBarMenu * Rename mobileMenuOpen -> menuOpen in NavBarNext (since it can be used for mobile menu or megamenu) * just use index to key the items * Use exact versions of @react-aria packages * Navigation: Make the dropdown header a NavBarMenuItem * Navigation: Stop using dropdown-menu for styles * Navigation: Add react-aria relevant packages * Navigation: Refactor NavBarDropdown to support react aria * Navigation: apply keyboard navigation to NavBar component * Navigation: UseHover hook for triggering submenu on navbar * Navigation: rename testMenu component to NavBarItemButton * WIP * some hacks * Refactor: clean up keybinding events * Navigation: render subtitle on item menu and disable it * Navigation: Adds react-aria types (#42113) * Refactor: refactor out to NavBarItemWithoutMenu * Refactor: cleaning up stuff * Refactor: comment out unused code * Chore: Removes section and uses items only * Chore: fix NavBarNext * Chore: adds tests * Refactor: minimize props api * Refactor: various refactors * Refactor: rename enableAllItems * Refactor: remove unused code * Refactor: fix clicking on menuitems * Refactor: use recommended onAction instead * Navigation: Fix a11y issues on NavBar * Navigation: Fix a11y navBar Next * Navigation: Remove unnecessary label prop, use link.text instead * Apply suggestions from code review Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> * Apply unit tests suggestions from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update react-aria/menu package to latest version and apply PR suggestion Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
4 years ago
);
}
NavBarMenuItem.displayName = 'NavBarMenuItem';
const getStyles = (theme: GrafanaTheme2, isActive: Props['isActive']) => ({
linkContent: css({
alignItems: 'center',
display: 'flex',
gap: '0.5rem',
width: '100%',
}),
linkText: css({
textOverflow: 'ellipsis',
overflow: 'hidden',
whiteSpace: 'nowrap',
}),
externalLinkIcon: css({
color: theme.colors.text.secondary,
gridColumnStart: 3,
}),
element: css({
alignItems: 'center',
background: 'none',
border: 'none',
color: isActive ? theme.colors.text.primary : theme.colors.text.secondary,
display: 'flex',
flex: 1,
fontSize: 'inherit',
height: '100%',
overflowWrap: 'anywhere',
padding: theme.spacing(0.5, 2),
textAlign: 'left',
width: '100%',
'&:hover, &:focus-visible': {
backgroundColor: theme.colors.action.hover,
color: theme.colors.text.primary,
},
'&:focus-visible': {
boxShadow: 'none',
outline: `2px solid ${theme.colors.primary.main}`,
outlineOffset: '-2px',
transition: 'none',
},
'&::before': {
display: isActive ? 'block' : 'none',
content: '" "',
position: 'absolute',
left: 0,
top: 0,
bottom: 0,
width: theme.spacing(0.5),
borderRadius: theme.shape.borderRadius(1),
backgroundImage: theme.colors.gradients.brandVertical,
},
}),
listItem: css({
position: 'relative',
display: 'flex',
alignItems: 'center',
'&:hover, &:focus-within': {
color: theme.colors.text.primary,
'> *:first-child::after': {
backgroundColor: theme.colors.action.hover,
},
},
}),
divider: css({
borderBottom: `1px solid ${theme.colors.border.weak}`,
height: '1px',
margin: `${theme.spacing(1)} 0`,
overflow: 'hidden',
}),
});