GrafanaUI: Mark ScrollContainer as stable and deprecate CustomScrollbar (#96331)

* deprecate CustomScrollbar, promote ScrollContainer

* add documentation start

* use the properly exported ScrollContainer

* Update packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.mdx

Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>

---------

Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
This commit is contained in:
Ashley Harrison 2024-11-14 12:06:21 +00:00 committed by GitHub
parent 324503ee8b
commit 192423956b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 232 additions and 56 deletions

View File

@ -17,11 +17,11 @@ import {
Icon,
InlineField,
InlineFieldRow,
ScrollContainer,
SelectMenuOptions,
useStyles2,
useTheme2,
} from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { PrometheusDatasource } from '../../datasource';
import { truncateResult } from '../../language_utils';

View File

@ -32,6 +32,7 @@ interface Props {
/**
* Wraps component into <Scrollbars> component from `react-custom-scrollbars`
* @deprecated Use `ScrollContainer` from `@grafana/ui` instead. It uses native scrollbars and has a simpler API.
*/
export const CustomScrollbar = ({
autoHide = false,

View File

@ -0,0 +1,65 @@
import { Meta, Preview, ArgTypes } from '@storybook/blocks';
import { ScrollContainer } from './ScrollContainer';
<Meta title="MDX|ScrollContainer" component={ScrollContainer} />
# ScrollContainer
This component is used to create a scrollable container. It uses native scrollbars, has an option to show scroll indicators, and supports most `Box` properties.
## Migrating from CustomScrollbar
ScrollContainer is intended to be a functionally equivalent replacement for CustomScrollbar. If you're not using any additional props in CustomScrollbar, it should be a drop-in replacement.
If you were using additional props, there are roughly 3 categories of changes:
1. Props that have been **renamed**
2. Props that have been removed but the **same behavior can be achieved in a different way**
3. Props that have been removed and are **no longer supported**
### Props that have been renamed
- `autoHeightMin` is now `minHeight`
- `autoHeightMax` is now `maxHeight`
- `divId` is now `id`
- `testId` is now `data-testid`
- `scrollRefCallback` is now `ref`
### Props that have been removed but the same behavior can be achieved in a different way
- `hideHorizontalTrack` and `hideVerticalTrack` have been removed.
- You can achieve the same behavior by setting either `overflowX` or `overflowY` to `hidden`. These names more closely match the CSS properties they represent.
- `scrollTop` and `setScrollTop`.
- You can achieve the same behavior by using the `ref` prop to get a reference to the `ScrollContainer` component, and then calling `scrollTo` on that reference.
- Before:
```tsx
const [scrollTop, setScrollTop] = useState(0);
return <CustomScrollbar scrollTop={scrollTop}>// Your amazing scrolling content</CustomScrollbar>;
```
- After:
```tsx
const [scrollTop, setScrollTop] = useState(0);
const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => {
scrollRef.current?.scrollTo(0, scrollTop);
}, [scrollTop]);
return <ScrollContainer ref={scrollRef}>// Your amazing scrolling content</ScrollContainer>;
```
### Props that have been removed and are no longer supported
- `autoHide`, `autoHideTimeout` and `hideTracksWhenNotNeeded`.
- These props no longer make sense when using native scrollbars, since some operating systems (Windows for example) don't have overlay scrollbars.
- `className`
- Like our other design system components, the intention is that you'll never need to write custom CSS for this component. We extend all the base `Box` props, so everything _should_ be available as a prop.
- `updateAfterMountMs`
- This wasn't very react-y, and could cause inconsistent behaviour.
<ArgTypes of={ScrollContainer} />

View File

@ -0,0 +1,93 @@
import { action } from '@storybook/addon-actions';
import { Meta, StoryFn } from '@storybook/react';
import { ScrollContainer } from './ScrollContainer';
import mdx from './ScrollContainer.mdx';
const meta: Meta<typeof ScrollContainer> = {
title: 'General/Layout/ScrollContainer',
component: ScrollContainer,
parameters: {
controls: {
exclude: ['onScroll'],
},
docs: {
page: mdx,
},
},
argTypes: {},
args: {
onScroll: action('onScroll'),
height: 50,
overflowX: 'auto',
overflowY: 'auto',
scrollbarWidth: 'thin',
showScrollIndicators: true,
width: 50,
},
};
export const Basic: StoryFn<typeof ScrollContainer> = (args) => {
return (
<ScrollContainer {...args} borderColor="info" borderStyle="dashed" padding={1}>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
</ScrollContainer>
);
};
export default meta;

View File

@ -9,7 +9,7 @@ import { Box, BoxProps } from '../Layout/Box/Box';
import { ScrollIndicators } from './ScrollIndicators';
interface Props extends Omit<BoxProps, 'display' | 'direction' | 'flex' | 'position'> {
interface Props extends Omit<BoxProps, 'display' | 'direction' | 'element' | 'flex' | 'position'> {
showScrollIndicators?: boolean;
onScroll?: UIEventHandler<HTMLDivElement>;
overflowX?: Property.OverflowX;

View File

@ -217,6 +217,7 @@ export { Box } from './Layout/Box/Box';
export { Stack } from './Layout/Stack/Stack';
export { Grid } from './Layout/Grid/Grid';
export { Space } from './Layout/Space';
export { ScrollContainer } from './ScrollContainer/ScrollContainer';
export { Label } from './Forms/Label';
export { Field, type FieldProps } from './Forms/Field';

View File

@ -10,4 +10,3 @@
*/
export * from './utils/skeleton';
export * from './components/ScrollContainer/ScrollContainer';

View File

@ -6,8 +6,7 @@ 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 { Icon, IconButton, useStyles2, Stack } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Icon, IconButton, ScrollContainer, useStyles2, Stack } from '@grafana/ui';
import { useGrafana } from 'app/core/context/GrafanaContext';
import { t } from 'app/core/internationalization';
import { setBookmark } from 'app/core/reducers/navBarTree';

View File

@ -1,9 +1,8 @@
import { css, cx } from '@emotion/css';
import { useEffect, useRef, useState } from 'react';
import { Button, Stack, TextLink, useStyles2, useTheme2 } from '@grafana/ui';
import { Button, ScrollContainer, Stack, TextLink, useStyles2, useTheme2 } from '@grafana/ui';
import { getSelectStyles } from '@grafana/ui/src/components/Select/getSelectStyles';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { OrgRole, Role } from 'app/types';
import { BuiltinRoleSelector } from './BuiltinRoleSelector';

View File

@ -1,8 +1,7 @@
import { cx } from '@emotion/css';
import { Button, Stack, useStyles2, useTheme2 } from '@grafana/ui';
import { Button, ScrollContainer, Stack, useStyles2, useTheme2 } from '@grafana/ui';
import { getSelectStyles } from '@grafana/ui/src/components/Select/getSelectStyles';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Role } from 'app/types';
import { RoleMenuOption } from './RoleMenuOption';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Alert, LoadingPlaceholder, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Alert, LoadingPlaceholder, ScrollContainer, useStyles2 } from '@grafana/ui';
import { contextSrv } from 'app/core/services/context_srv';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';

View File

@ -11,8 +11,7 @@ import {
SceneObjectUrlValues,
VizPanel,
} from '@grafana/scenes';
import { Container, TabContent, TabsBar, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Container, ScrollContainer, TabContent, TabsBar, useStyles2 } from '@grafana/ui';
import { getConfig } from 'app/core/config';
import { contextSrv } from 'app/core/core';
import { getRulesPermissions } from 'app/features/alerting/unified/utils/access-control';

View File

@ -22,8 +22,16 @@ import {
VizPanel,
sceneGraph,
} from '@grafana/scenes';
import { Button, Card, FilterInput, RadioButtonGroup, Stack, ToolbarButton, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import {
Button,
Card,
FilterInput,
RadioButtonGroup,
ScrollContainer,
Stack,
ToolbarButton,
useStyles2,
} from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { OptionFilter } from 'app/features/dashboard/components/PanelEditor/OptionsPaneOptions';
import { getPanelPluginNotFound } from 'app/features/panel/components/PanelPluginError';

View File

@ -7,8 +7,7 @@ import { GrafanaTheme2, PanelData, SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { reportInteraction } from '@grafana/runtime';
import { VizPanel } from '@grafana/scenes';
import { Button, Field, FilterInput, RadioButtonGroup, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Button, Field, FilterInput, RadioButtonGroup, ScrollContainer, useStyles2 } from '@grafana/ui';
import { LS_VISUALIZATION_SELECT_TAB_KEY } from 'app/core/constants';
import { VisualizationSelectPaneTab } from 'app/features/dashboard/components/PanelEditor/types';
import { VisualizationSuggestions } from 'app/features/panel/components/VizTypePicker/VisualizationSuggestions';

View File

@ -4,8 +4,7 @@ import * as React from 'react';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { config } from '@grafana/runtime';
import { FilterInput, RadioButtonGroup, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { FilterInput, RadioButtonGroup, ScrollContainer, useStyles2 } from '@grafana/ui';
import { AngularDeprecationPluginNotice } from 'app/features/plugins/angularDeprecation/AngularDeprecationPluginNotice';
import { isPanelModelLibraryPanel } from '../../../library-panels/guard';

View File

@ -4,9 +4,8 @@ import { useLocalStorage } from 'react-use';
import { GrafanaTheme2, PanelData, SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Button, FilterInput, RadioButtonGroup, useStyles2 } from '@grafana/ui';
import { Button, FilterInput, RadioButtonGroup, ScrollContainer, useStyles2 } from '@grafana/ui';
import { Field } from '@grafana/ui/src/components/Forms/Field';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { LS_VISUALIZATION_SELECT_TAB_KEY } from 'app/core/constants';
import { PanelLibraryOptionsGroup } from 'app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup';
import { VisualizationSuggestions } from 'app/features/panel/components/VizTypePicker/VisualizationSuggestions';

View File

@ -6,9 +6,8 @@ import { GrafanaTheme2, ScopedVars } from '@grafana/data';
import { sanitize, sanitizeUrl } from '@grafana/data/src/text/sanitize';
import { selectors } from '@grafana/e2e-selectors';
import { DashboardLink } from '@grafana/schema';
import { Dropdown, Icon, Button, Menu, useStyles2 } from '@grafana/ui';
import { Dropdown, Icon, Button, Menu, ScrollContainer, useStyles2 } from '@grafana/ui';
import { ButtonLinkProps, LinkButton } from '@grafana/ui/src/components/Button';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { getBackendSrv } from 'app/core/services/backend_srv';
import { DashboardSearchItem } from 'app/features/search/types';

View File

@ -13,8 +13,16 @@ import {
} from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { reportInteraction } from '@grafana/runtime';
import { Button, ConfirmModal, Container, Themeable, withTheme, IconButton, ButtonGroup } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import {
Button,
ConfirmModal,
Container,
Themeable,
withTheme,
IconButton,
ButtonGroup,
ScrollContainer,
} from '@grafana/ui';
import config from 'app/core/config';
import { EmptyTransformationsMessage } from 'app/features/dashboard-scene/panel-edit/PanelDataPane/EmptyTransformationsMessage';

View File

@ -5,8 +5,15 @@ import { useMemo, useState } from 'react';
import { DataSourceInstanceSettings, DataSourceRef, GrafanaTheme2 } from '@grafana/data';
import { config, reportInteraction } from '@grafana/runtime';
import { DataQuery } from '@grafana/schema';
import { Modal, FileDropzone, FileDropzoneDefaultChildren, useStyles2, Input, Icon } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import {
Modal,
FileDropzone,
FileDropzoneDefaultChildren,
useStyles2,
Input,
Icon,
ScrollContainer,
} from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import * as DFImport from 'app/features/dataframe-import';
import { GrafanaQuery } from 'app/plugins/datasource/grafana/types';

View File

@ -12,8 +12,7 @@ import { DataSourceInstanceSettings, GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { reportInteraction } from '@grafana/runtime';
import { DataQuery, DataSourceRef } from '@grafana/schema';
import { Button, Icon, Input, ModalsController, Portal, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Button, Icon, Input, ModalsController, Portal, ScrollContainer, useStyles2 } from '@grafana/ui';
import config from 'app/core/config';
import { Trans } from 'app/core/internationalization';
import { useKeyNavigationListener } from 'app/features/search/hooks/useSearchKeyboardSelection';

View File

@ -4,8 +4,7 @@ import { useToggle, useScroll } from 'react-use';
import { GrafanaTheme2, store } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import { useStyles2, PanelContainer } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { useStyles2, PanelContainer, ScrollContainer } from '@grafana/ui';
import { ContentOutlineItemContextProps, useContentOutlineContext } from './ContentOutlineContext';
import { ContentOutlineItemButton } from './ContentOutlineItemButton';

View File

@ -20,9 +20,15 @@ import {
import { selectors } from '@grafana/e2e-selectors';
import { getDataSourceSrv, reportInteraction } from '@grafana/runtime';
import { DataQuery } from '@grafana/schema';
import { AdHocFilterItem, ErrorBoundaryAlert, PanelContainer, Themeable2, withTheme2 } from '@grafana/ui';
import {
AdHocFilterItem,
ErrorBoundaryAlert,
PanelContainer,
ScrollContainer,
Themeable2,
withTheme2,
} from '@grafana/ui';
import { FILTER_FOR_OPERATOR, FILTER_OUT_OPERATOR } from '@grafana/ui/src/components/Table/types';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { supportedFeatures } from 'app/core/history/richHistoryStorageProvider';
import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource';
import { StoreState } from 'app/types';

View File

@ -2,8 +2,7 @@ import { css, cx } from '@emotion/css';
import { dateTimeFormat, systemDateFormats, GrafanaTheme2 } from '@grafana/data';
import { TimeZone } from '@grafana/schema';
import { Spinner, useTheme2, clearButtonStyles } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { ScrollContainer, Spinner, useTheme2, clearButtonStyles } from '@grafana/ui';
import { LogsPage } from './LogsNavigation';

View File

@ -16,8 +16,7 @@ import {
import { selectors } from '@grafana/e2e-selectors';
import { getDataSourceSrv, locationService } from '@grafana/runtime';
import { DataQuery } from '@grafana/schema';
import { Button, HorizontalGroup, InlineFormLabel, Modal, stylesFactory } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Button, HorizontalGroup, InlineFormLabel, Modal, ScrollContainer, stylesFactory } from '@grafana/ui';
import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp';
import config from 'app/core/config';
import { backendSrv } from 'app/core/services/backend_srv';

View File

@ -4,8 +4,7 @@ import { finalize, from, Subscription } from 'rxjs';
import { GrafanaTheme2, ScopeDashboardBinding } from '@grafana/data';
import { SceneComponentProps, SceneObjectBase, SceneObjectRef, SceneObjectState } from '@grafana/scenes';
import { Button, LoadingPlaceholder, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Button, LoadingPlaceholder, ScrollContainer, useStyles2 } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import { ScopesDashboardsTree } from './ScopesDashboardsTree';

View File

@ -2,8 +2,7 @@ import { css, cx } from '@emotion/css';
import { Dictionary } from 'lodash';
import { GrafanaTheme2 } from '@grafana/data';
import { Checkbox, Icon, RadioButtonDot, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Checkbox, Icon, RadioButtonDot, ScrollContainer, useStyles2 } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { ScopesTree } from './ScopesTree';

View File

@ -4,10 +4,9 @@ import { FormEvent, useCallback, useEffect, useRef, useState } from 'react';
import * as React from 'react';
import { GrafanaTheme2, VariableSuggestion } from '@grafana/data';
import { FieldValidationMessage, Portal, TextArea, useTheme2 } from '@grafana/ui';
import { FieldValidationMessage, Portal, ScrollContainer, TextArea, useTheme2 } from '@grafana/ui';
import { DataLinkSuggestions } from '@grafana/ui/src/components/DataLinks/DataLinkSuggestions';
import { Input } from '@grafana/ui/src/components/Input/Input';
import { ScrollContainer } from '@grafana/ui/src/unstable';
const modulo = (a: number, n: number) => a - n * Math.floor(a / n);
const ERROR_TOOLTIP_OFFSET = 8;

View File

@ -3,8 +3,17 @@ import { useEffect, useMemo, useState } from 'react';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import { Button, Card, Collapse, Field, Input, LoadingPlaceholder, Select, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import {
Button,
Card,
Collapse,
Field,
Input,
LoadingPlaceholder,
ScrollContainer,
Select,
useStyles2,
} from '@grafana/ui';
import AzureLogAnalyticsDatasource from '../../azure_log_analytics/azure_log_analytics_datasource';
import {

View File

@ -12,9 +12,9 @@ import {
BigValueJustifyMode,
BigValueTextMode,
LoadingPlaceholder,
ScrollContainer,
useStyles2,
} from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { config } from 'app/core/config';
import alertDef from 'app/features/alerting/state/alertDef';
import { alertRuleApi } from 'app/features/alerting/unified/api/alertRuleApi';

View File

@ -13,9 +13,8 @@ import {
PanelProps,
} from '@grafana/data';
import { config, getBackendSrv, locationService } from '@grafana/runtime';
import { Button, stylesFactory, TagList } from '@grafana/ui';
import { Button, ScrollContainer, stylesFactory, TagList } from '@grafana/ui';
import { AbstractList } from '@grafana/ui/src/components/List/AbstractList';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import appEvents from 'app/core/app_events';
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';

View File

@ -11,8 +11,7 @@ import {
UrlQueryValue,
urlUtil,
} from '@grafana/data';
import { useStyles2, IconButton } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { useStyles2, IconButton, ScrollContainer } from '@grafana/ui';
import { updateNavIndex } from 'app/core/actions';
import { getConfig } from 'app/core/config';
import { appEvents } from 'app/core/core';

View File

@ -20,8 +20,7 @@ import {
toUtc,
urlUtil,
} from '@grafana/data';
import { usePanelContext, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { ScrollContainer, usePanelContext, useStyles2 } from '@grafana/ui';
import { getFieldLinksForExplore } from 'app/features/explore/utils/links';
import { LogRowContextModal } from 'app/features/logs/components/log-context/LogRowContextModal';
import { PanelDataErrorView } from 'app/features/panel/components/PanelDataErrorView';

View File

@ -2,8 +2,7 @@ import { useEffect } from 'react';
import { PanelProps } from '@grafana/data';
import { RefreshEvent } from '@grafana/runtime';
import { Alert, Icon } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { Alert, Icon, ScrollContainer } from '@grafana/ui';
import { News } from './component/News';
import { DEFAULT_FEED_URL } from './constants';

View File

@ -4,8 +4,7 @@ import { useState } from 'react';
import { useDebounce } from 'react-use';
import { GrafanaTheme2, PanelProps, renderTextPanelMarkdown, textUtil, InterpolateFunction } from '@grafana/data';
import { CodeEditor, useStyles2 } from '@grafana/ui';
import { ScrollContainer } from '@grafana/ui/src/unstable';
import { CodeEditor, ScrollContainer, useStyles2 } from '@grafana/ui';
import config from 'app/core/config';
import { defaultCodeOptions, Options, TextMode } from './panelcfg.gen';