From ada6249280e830920cea05b72d58cbd45385e85d Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Thu, 31 Oct 2024 15:27:35 +0000 Subject: [PATCH] Chore: use `ScrollContainer` across frontend platform components (#95601) * use ScrollContainer in grafana-ui * remove extraneous labels * fix unit tests --- .../components/DataLinks/DataLinkInput.tsx | 17 +++++++----- .../RelativeTimeRangePicker.tsx | 20 +++++++------- .../src/components/Drawer/Drawer.tsx | 4 +-- .../components/Forms/Legacy/Select/Select.tsx | 6 ++--- .../src/components/Select/SelectBase.test.tsx | 3 --- .../src/components/Select/SelectMenu.tsx | 6 ++--- .../TabbedContainer/TabbedContainer.tsx | 6 ++--- .../components/Toggletip/Toggletip.story.tsx | 6 ++--- .../AppChrome/MegaMenu/MegaMenu.tsx | 7 ++--- .../alerting/unified/Silences.test.tsx | 2 -- .../SpanFilters/SpanFilters.test.tsx | 26 +++++++++---------- 11 files changed, 53 insertions(+), 50 deletions(-) diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx index 96c442a3458..5f91741bfd4 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx @@ -13,9 +13,9 @@ import { DataLinkBuiltInVars, GrafanaTheme2, VariableOrigin, VariableSuggestion import { SlatePrism } from '../../slate-plugins'; import { useStyles2 } from '../../themes'; import { SCHEMA, makeValue } from '../../utils/slate'; -import CustomScrollbar from '../CustomScrollbar/CustomScrollbar'; import { getInputStyles } from '../Input/Input'; import { Portal } from '../Portal/Portal'; +import { ScrollContainer } from '../ScrollContainer/ScrollContainer'; import { DataLinkSuggestions } from './DataLinkSuggestions'; import { SelectionReference } from './SelectionReference'; @@ -86,6 +86,11 @@ export const DataLinkInput = memo( const [linkUrl, setLinkUrl] = useState(makeValue(value)); const prevLinkUrl = usePrevious(linkUrl); const [scrollTop, setScrollTop] = useState(0); + const scrollRef = useRef(null); + + useEffect(() => { + scrollRef.current?.scrollTo(0, scrollTop); + }, [scrollTop]); // the order of middleware is important! const middleware = [ @@ -208,10 +213,10 @@ export const DataLinkInput = memo( {showingSuggestions && (
- setScrollTop(scrollTop)} + setScrollTop(event.currentTarget.scrollTop)} > setShowingSuggestions(false)} activeIndex={suggestionsIndex} /> - +
)} diff --git a/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx index 5e4c0d57ba4..ebe703f905b 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx @@ -10,10 +10,10 @@ import { RelativeTimeRange, GrafanaTheme2, TimeOption } from '@grafana/data'; import { useStyles2 } from '../../../themes'; import { Trans, t } from '../../../utils/i18n'; import { Button } from '../../Button'; -import CustomScrollbar from '../../CustomScrollbar/CustomScrollbar'; import { Field } from '../../Forms/Field'; import { Icon } from '../../Icon/Icon'; import { getInputStyles, Input } from '../../Input/Input'; +import { ScrollContainer } from '../../ScrollContainer/ScrollContainer'; import { Tooltip } from '../../Tooltip/Tooltip'; import { TimePickerTitle } from '../TimeRangePicker/TimePickerTitle'; import { TimeRangeList } from '../TimeRangePicker/TimeRangeList'; @@ -157,14 +157,16 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
- - - +
+ + + +
diff --git a/packages/grafana-ui/src/components/Drawer/Drawer.tsx b/packages/grafana-ui/src/components/Drawer/Drawer.tsx index df030a19d28..d4ef3502698 100644 --- a/packages/grafana-ui/src/components/Drawer/Drawer.tsx +++ b/packages/grafana-ui/src/components/Drawer/Drawer.tsx @@ -11,9 +11,9 @@ import { selectors } from '@grafana/e2e-selectors'; import { useStyles2 } from '../../themes'; import { t } from '../../utils/i18n'; -import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; import { getDragStyles } from '../DragHandle/DragHandle'; import { IconButton } from '../IconButton/IconButton'; +import { ScrollContainer } from '../ScrollContainer/ScrollContainer'; import { Text } from '../Text/Text'; import 'rc-drawer/assets/index.css'; @@ -167,7 +167,7 @@ export function Drawer({
)} {typeof title !== 'string' && title} - {!scrollableContent ? content : {content}} + {!scrollableContent ? content : {content}}
diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.tsx index f449c7cee47..f572ef55401 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.tsx @@ -9,7 +9,7 @@ import Creatable from 'react-select/creatable'; // Components import { SelectableValue, ThemeContext } from '@grafana/data'; -import { CustomScrollbar } from '../../../CustomScrollbar/CustomScrollbar'; +import { ScrollContainer } from '../../../ScrollContainer/ScrollContainer'; import { SingleValue } from '../../../Select/SingleValue'; import resetSelectStyles from '../../../Select/resetSelectStyles'; import { SelectCommonProps, SelectAsyncProps } from '../../../Select/types'; @@ -45,9 +45,9 @@ export interface LegacySelectProps extends LegacyCommonProps { export const MenuList = (props: MenuListProps) => { return ( - + {props.children} - + ); }; diff --git a/packages/grafana-ui/src/components/Select/SelectBase.test.tsx b/packages/grafana-ui/src/components/Select/SelectBase.test.tsx index ac41aa47c03..3c0dc9446a2 100644 --- a/packages/grafana-ui/src/components/Select/SelectBase.test.tsx +++ b/packages/grafana-ui/src/components/Select/SelectBase.test.tsx @@ -267,9 +267,6 @@ describe('SelectBase', () => { }); describe('toggle all', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); it('renders menu with select all toggle', async () => { render( - + {toggleAllOptions && ( )} {children} - +
); }; diff --git a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx index 3feff5be763..07fb0ad039d 100644 --- a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx +++ b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx @@ -8,7 +8,7 @@ import { IconButton } from '../../components/IconButton/IconButton'; import { TabsBar, Tab, TabContent } from '../../components/Tabs'; import { useStyles2, useTheme2 } from '../../themes'; import { IconName } from '../../types/icon'; -import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; +import { ScrollContainer } from '../ScrollContainer/ScrollContainer'; export interface TabConfig { label: string; @@ -50,9 +50,9 @@ export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, t ))} - + {tabs.find((t) => t.value === activeTab)?.content} - +
); } diff --git a/packages/grafana-ui/src/components/Toggletip/Toggletip.story.tsx b/packages/grafana-ui/src/components/Toggletip/Toggletip.story.tsx index 5e600869666..9a81241cbca 100644 --- a/packages/grafana-ui/src/components/Toggletip/Toggletip.story.tsx +++ b/packages/grafana-ui/src/components/Toggletip/Toggletip.story.tsx @@ -1,7 +1,7 @@ import { Meta, StoryFn } from '@storybook/react'; import { Button } from '../Button'; -import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; +import { ScrollContainer } from '../ScrollContainer/ScrollContainer'; import mdx from '../Toggletip/Toggletip.mdx'; import { Toggletip } from './Toggletip'; @@ -96,7 +96,7 @@ export const LongContent: StoryFn = ({ Toggletip with scrollable content and no interactive controls} content={ - + {/* one of the few documented cases we can turn this rule off */} {/* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-noninteractive-tabindex.md#case-shouldnt-i-add-a-tabindex-so-that-users-can-navigate-to-this-item */} {/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */} @@ -110,7 +110,7 @@ export const LongContent: StoryFn = ({

This is some content repeated over and over again to ensure it is scrollable.

))}
- + } footer={footer} theme={theme} diff --git a/public/app/core/components/AppChrome/MegaMenu/MegaMenu.tsx b/public/app/core/components/AppChrome/MegaMenu/MegaMenu.tsx index 28d92b890f4..38b61edad70 100644 --- a/public/app/core/components/AppChrome/MegaMenu/MegaMenu.tsx +++ b/public/app/core/components/AppChrome/MegaMenu/MegaMenu.tsx @@ -6,7 +6,8 @@ import { useLocation } from 'react-router-dom-v5-compat'; import { GrafanaTheme2, NavModelItem } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { config, reportInteraction } from '@grafana/runtime'; -import { CustomScrollbar, Icon, IconButton, useStyles2, Stack } from '@grafana/ui'; +import { Icon, IconButton, useStyles2, Stack } from '@grafana/ui'; +import { ScrollContainer } from '@grafana/ui/src/unstable'; import { useGrafana } from 'app/core/context/GrafanaContext'; import { t } from 'app/core/internationalization'; import { setBookmark } from 'app/core/reducers/navBarTree'; @@ -134,7 +135,7 @@ export const MegaMenu = memo( )} ); diff --git a/public/app/features/alerting/unified/Silences.test.tsx b/public/app/features/alerting/unified/Silences.test.tsx index e2b2f134ca2..416dfe024eb 100644 --- a/public/app/features/alerting/unified/Silences.test.tsx +++ b/public/app/features/alerting/unified/Silences.test.tsx @@ -120,8 +120,6 @@ beforeEach(() => { ]); }); -afterEach(() => jest.resetAllMocks()); - describe('Silences', () => { it( 'loads and shows silences', diff --git a/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.test.tsx b/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.test.tsx index fea0ba6917a..9ecb184f686 100644 --- a/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.test.tsx +++ b/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.test.tsx @@ -185,19 +185,19 @@ describe('SpanFilters', () => { jest.advanceTimersByTime(1000); await waitFor(() => { const container = screen.getByText('TagKey0').parentElement?.parentElement?.parentElement; - expect(container?.childNodes[0].textContent).toBe('ProcessKey0'); - expect(container?.childNodes[1].textContent).toBe('ProcessKey1'); - expect(container?.childNodes[2].textContent).toBe('TagKey0'); - expect(container?.childNodes[3].textContent).toBe('TagKey1'); - expect(container?.childNodes[4].textContent).toBe('id'); - expect(container?.childNodes[5].textContent).toBe('kind'); - expect(container?.childNodes[6].textContent).toBe('library.name'); - expect(container?.childNodes[7].textContent).toBe('library.version'); - expect(container?.childNodes[8].textContent).toBe('status'); - expect(container?.childNodes[9].textContent).toBe('status.message'); - expect(container?.childNodes[10].textContent).toBe('trace.state'); - expect(container?.childNodes[11].textContent).toBe('LogKey0'); - expect(container?.childNodes[12].textContent).toBe('LogKey1'); + expect(container?.childNodes[1].textContent).toBe('ProcessKey0'); + expect(container?.childNodes[2].textContent).toBe('ProcessKey1'); + expect(container?.childNodes[3].textContent).toBe('TagKey0'); + expect(container?.childNodes[4].textContent).toBe('TagKey1'); + expect(container?.childNodes[5].textContent).toBe('id'); + expect(container?.childNodes[6].textContent).toBe('kind'); + expect(container?.childNodes[7].textContent).toBe('library.name'); + expect(container?.childNodes[8].textContent).toBe('library.version'); + expect(container?.childNodes[9].textContent).toBe('status'); + expect(container?.childNodes[10].textContent).toBe('status.message'); + expect(container?.childNodes[11].textContent).toBe('trace.state'); + expect(container?.childNodes[12].textContent).toBe('LogKey0'); + expect(container?.childNodes[13].textContent).toBe('LogKey1'); }); });