diff --git a/packages/grafana-ui/src/themes/GlobalStyles/elements.ts b/packages/grafana-ui/src/themes/GlobalStyles/elements.ts index 49f8f4d6dc5..8f2580de8bb 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/elements.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/elements.ts @@ -55,6 +55,9 @@ export function getElementStyles(theme: GrafanaTheme2) { button { letter-spacing: ${theme.typography.body.letterSpacing}; + &:focus-visible { + outline: ${getFocusStyles(theme)}; + } &:focus { outline: none; } diff --git a/public/app/core/components/sidemenu/TopSection.test.tsx b/public/app/core/components/sidemenu/TopSection.test.tsx index 6ed01479833..cebadab7e7a 100644 --- a/public/app/core/components/sidemenu/TopSection.test.tsx +++ b/public/app/core/components/sidemenu/TopSection.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { render, screen } from '@testing-library/react'; import TopSection from './TopSection'; jest.mock('../../config', () => ({ @@ -9,33 +9,21 @@ jest.mock('../../config', () => ({ { id: '2', hideFromMenu: true }, { id: '3', hideFromMenu: false }, { id: '4', hideFromMenu: true }, + { id: '4', hideFromMenu: false }, ], }, })); -const setup = (propOverrides?: object) => { - const props = Object.assign( - { - mainLinks: [], - }, - propOverrides - ); - - return shallow(); -}; - describe('Render', () => { - it('should render component', () => { - const wrapper = setup(); + it('should render search when empty', () => { + render(); - expect(wrapper).toMatchSnapshot(); + expect(screen.getByText('Search dashboards')).toBeInTheDocument(); }); - it('should render items', () => { - const wrapper = setup({ - mainLinks: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }], - }); + it('should render items and search item', () => { + render(); - expect(wrapper).toMatchSnapshot(); + expect(screen.getByTestId('top-section-items').children.length).toBe(3); }); }); diff --git a/public/app/core/components/sidemenu/TopSection.tsx b/public/app/core/components/sidemenu/TopSection.tsx index 9e8b4299539..8ee7669ecb2 100644 --- a/public/app/core/components/sidemenu/TopSection.tsx +++ b/public/app/core/components/sidemenu/TopSection.tsx @@ -8,7 +8,7 @@ const TopSection: FC = () => { const navTree = cloneDeep(config.bootData.navTree); const mainLinks = filter(navTree, (item) => !item.hideFromMenu); const searchLink = { - text: 'Search', + text: 'Search dashboards', icon: 'search', }; @@ -17,7 +17,7 @@ const TopSection: FC = () => { }; return ( -
+
{mainLinks.map((link, index) => { return ; diff --git a/public/app/core/components/sidemenu/TopSectionItem.tsx b/public/app/core/components/sidemenu/TopSectionItem.tsx index dba932fc717..ef05287d8c6 100644 --- a/public/app/core/components/sidemenu/TopSectionItem.tsx +++ b/public/app/core/components/sidemenu/TopSectionItem.tsx @@ -1,7 +1,8 @@ import React, { FC } from 'react'; import SideMenuDropDown from './SideMenuDropDown'; -import { Icon, Link } from '@grafana/ui'; +import { Icon, Link, useStyles2 } from '@grafana/ui'; import { NavModelItem } from '@grafana/data'; +import { css, cx } from '@emotion/css'; export interface Props { link: NavModelItem; @@ -9,6 +10,13 @@ export interface Props { } const TopSectionItem: FC = ({ link, onClick }) => { + const resetButtonStyles = useStyles2( + () => + css` + background-color: transparent; + ` + ); + const linkContent = ( {link.icon && } @@ -28,9 +36,9 @@ const TopSectionItem: FC = ({ link, onClick }) => { {linkContent} ) : ( - + ); return (
diff --git a/public/app/core/components/sidemenu/__snapshots__/TopSection.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/TopSection.test.tsx.snap deleted file mode 100644 index 374763031a5..00000000000 --- a/public/app/core/components/sidemenu/__snapshots__/TopSection.test.tsx.snap +++ /dev/null @@ -1,51 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Render should render component 1`] = ` -
- - -
-`; - -exports[`Render should render items 1`] = ` -
- - -
-`;