Chore: Clean up usage of deprecated stylesFactory function (#78419)

pull/78476/head
kay delaney 2 years ago committed by GitHub
parent 165de515cd
commit 9e11779921
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx
  2. 39
      packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx
  3. 5
      packages/grafana-ui/src/components/Card/Card.tsx
  4. 17
      packages/grafana-ui/src/components/Card/CardContainer.tsx
  5. 9
      packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx
  6. 9
      packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx
  7. 9
      packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx
  8. 2
      packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx
  9. 10
      packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx
  10. 5
      packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx
  11. 4
      packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx
  12. 36
      packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx
  13. 9
      packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx
  14. 42
      packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeList.tsx
  15. 13
      packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOption.tsx
  16. 26
      packages/grafana-ui/src/components/ErrorBoundary/ErrorWithStack.tsx
  17. 5
      packages/grafana-ui/src/components/Forms/Checkbox.tsx
  18. 61
      packages/grafana-ui/src/components/Forms/Field.tsx
  19. 9
      packages/grafana-ui/src/components/Forms/FieldSet.tsx
  20. 37
      packages/grafana-ui/src/components/Forms/FieldValidationMessage.tsx
  21. 55
      packages/grafana-ui/src/components/Forms/Label.tsx
  22. 9
      packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButton.tsx
  23. 10
      packages/grafana-ui/src/components/IconButton/IconButton.tsx
  24. 6
      packages/grafana-ui/src/components/InfoBox/InfoBox.tsx
  25. 8
      packages/grafana-ui/src/components/Modal/Modal.tsx
  26. 6
      packages/grafana-ui/src/components/Modal/getModalStyles.ts
  27. 33
      packages/grafana-ui/src/components/Select/InputControl.tsx
  28. 12
      packages/grafana-ui/src/components/Select/SelectContainer.tsx
  29. 5
      packages/grafana-ui/src/components/Slider/RangeSlider.tsx
  30. 5
      packages/grafana-ui/src/components/Slider/Slider.tsx
  31. 6
      packages/grafana-ui/src/components/Slider/styles.ts
  32. 12
      packages/grafana-ui/src/components/Switch/Switch.tsx
  33. 64
      packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx
  34. 20
      packages/grafana-ui/src/components/Table/FilterList.tsx
  35. 26
      packages/grafana-ui/src/components/Tabs/Counter.tsx
  36. 19
      packages/grafana-ui/src/components/Tabs/TabContent.tsx
  37. 9
      packages/grafana-ui/src/components/TextArea/TextArea.tsx
  38. 41
      packages/grafana-ui/src/components/transitions/FadeTransition.tsx
  39. 47
      packages/grafana-ui/src/components/transitions/SlideOutTransition.tsx
  40. 36
      packages/grafana-ui/src/graveyard/Graph/GraphWithLegend.tsx
  41. 11
      public/app/core/navigation/GrafanaRouteError.tsx
  42. 9
      public/app/features/dashboard/components/RowOptions/RowOptionsModal.tsx
  43. 82
      public/app/features/dimensions/editors/ResourceCards.tsx
  44. 80
      public/app/features/explore/ExploreDrawer.tsx
  45. 10
      public/app/features/geo/editor/GazetteerPathEditor.tsx
  46. 8
      public/app/features/inspector/InspectStatsTable.tsx
  47. 13
      public/app/features/inspector/InspectStatsTraceIdsTable.tsx
  48. 6
      public/app/features/live/dashboard/DashboardChangedModal.tsx
  49. 9
      public/app/features/users/TokenRevokedModal.tsx
  50. 9
      public/app/plugins/datasource/azuremonitor/components/Space.tsx
  51. 9
      public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/MultiFilterItem.tsx
  52. 9
      public/app/plugins/datasource/cloudwatch/components/shared/Dimensions/FilterItem.tsx
  53. 55
      public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx
  54. 9
      public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/EditorField.tsx

@ -1,20 +1,20 @@
import { css, cx } from '@emotion/css';
import React from 'react';
import { stylesFactory } from '../../themes';
import { useStyles2 } from '../../themes';
export interface Props {
className?: string;
}
export const FullWidthButtonContainer = ({ className, children }: React.PropsWithChildren<Props>) => {
const styles = getStyles();
const styles = useStyles2(getStyles);
return <div className={cx(styles, className)}>{children}</div>;
};
const getStyles = stylesFactory(() => {
return css({
const getStyles = () =>
css({
display: 'flex',
button: {
@ -31,4 +31,3 @@ const getStyles = stylesFactory(() => {
textAlign: 'center',
},
});
});

@ -4,7 +4,7 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { IconName } from '../../types/icon';
import { Button, ButtonProps } from '../Button';
import { CascaderOption } from '../Cascader/Cascader';
@ -27,27 +27,9 @@ export interface ButtonCascaderProps {
hideDownIcon?: boolean;
}
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
popup: css({
label: 'popup',
zIndex: theme.zIndex.dropdown,
}),
icons: {
right: css({
margin: '1px 0 0 4px',
}),
left: css({
margin: '-1px 4px 0 0',
}),
},
};
});
export const ButtonCascader = (props: ButtonCascaderProps) => {
const { onChange, className, loadData, icon, buttonProps, hideDownIcon, variant, disabled, ...rest } = props;
const theme = useTheme2();
const styles = getStyles(theme);
const styles = useStyles2(getStyles);
// Weird way to do this bit it goes around a styling issue in Button where even null/undefined child triggers
// styling change which messes up the look if there is only single icon content.
@ -72,3 +54,20 @@ export const ButtonCascader = (props: ButtonCascaderProps) => {
};
ButtonCascader.displayName = 'ButtonCascader';
const getStyles = (theme: GrafanaTheme2) => {
return {
popup: css({
label: 'popup',
zIndex: theme.zIndex.dropdown,
}),
icons: {
right: css({
margin: '1px 0 0 4px',
}),
left: css({
margin: '-1px 4px 0 0',
}),
},
};
};

@ -3,7 +3,7 @@ import React, { memo, cloneElement, FC, useMemo, useContext, ReactNode } from 'r
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2, useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { getFocusStyles } from '../../themes/mixins';
import { CardContainer, CardContainerProps, getCardContainerStyles } from './CardContainer';
@ -55,8 +55,7 @@ export const Card: CardInterface = ({ disabled, href, onClick, children, isSelec
const disableHover = disabled || (!onClick && !href);
const onCardClick = onClick && !disabled ? onClick : undefined;
const theme = useTheme2();
const styles = getCardContainerStyles(theme, disabled, disableHover, isSelected);
const styles = useStyles2(getCardContainerStyles, disabled, disableHover, isSelected);
return (
<CardContainer

@ -3,7 +3,7 @@ import React, { HTMLAttributes } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { styleMixins, stylesFactory, useStyles2, useTheme2 } from '../../themes';
import { styleMixins, useStyles2 } from '../../themes';
/**
* @public
@ -57,8 +57,8 @@ export const CardContainer = ({
href,
...props
}: CardContainerProps) => {
const theme = useTheme2();
const { oldContainer } = getCardContainerStyles(theme, disableEvents, disableHover, isSelected);
const { oldContainer } = useStyles2(getCardContainerStyles, disableEvents, disableHover, isSelected);
return (
<div {...props} className={cx(oldContainer, className)}>
<CardInner href={href}>{children}</CardInner>
@ -66,8 +66,12 @@ export const CardContainer = ({
);
};
export const getCardContainerStyles = stylesFactory(
(theme: GrafanaTheme2, disabled = false, disableHover = false, isSelected) => {
export const getCardContainerStyles = (
theme: GrafanaTheme2,
disabled = false,
disableHover = false,
isSelected?: boolean
) => {
const isSelectable = isSelected !== undefined;
return {
@ -132,5 +136,4 @@ export const getCardContainerStyles = stylesFactory(
}),
}),
};
}
);
};

@ -4,7 +4,7 @@ import React, { useState } from 'react';
import { DataFrame, DataLink, GrafanaTheme2, VariableSuggestion } from '@grafana/data';
import { stylesFactory, useTheme2 } from '../../../themes';
import { useStyles2 } from '../../../themes';
import { Button } from '../../Button/Button';
import { Modal } from '../../Modal/Modal';
@ -19,11 +19,10 @@ interface DataLinksInlineEditorProps {
}
export const DataLinksInlineEditor = ({ links, onChange, getSuggestions, data }: DataLinksInlineEditorProps) => {
const theme = useTheme2();
const [editIndex, setEditIndex] = useState<number | null>(null);
const [isNew, setIsNew] = useState(false);
const styles = getDataLinksInlineEditorStyles(theme);
const styles = useStyles2(getDataLinksInlineEditorStyles);
const linksSafe: DataLink[] = links ?? [];
const isEditing = editIndex !== null;
@ -110,10 +109,8 @@ export const DataLinksInlineEditor = ({ links, onChange, getSuggestions, data }:
);
};
const getDataLinksInlineEditorStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getDataLinksInlineEditorStyles = (theme: GrafanaTheme2) => ({
wrapper: css({
marginBottom: theme.spacing(2),
}),
};
});

@ -3,7 +3,7 @@ import React from 'react';
import { DataFrame, DataLink, GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '../../../themes';
import { useStyles2 } from '../../../themes';
import { isCompactUrl } from '../../../utils/dataLinks';
import { FieldValidationMessage } from '../../Forms/FieldValidationMessage';
import { IconButton } from '../../IconButton/IconButton';
@ -19,8 +19,7 @@ export interface DataLinksListItemProps {
}
export const DataLinksListItem = ({ link, onEdit, onRemove }: DataLinksListItemProps) => {
const theme = useTheme2();
const styles = getDataLinkListItemStyles(theme);
const styles = useStyles2(getDataLinkListItemStyles);
const { title = '', url = '' } = link;
const hasTitle = title.trim() !== '';
@ -52,7 +51,7 @@ export const DataLinksListItem = ({ link, onEdit, onRemove }: DataLinksListItemP
);
};
const getDataLinkListItemStyles = stylesFactory((theme: GrafanaTheme2) => {
const getDataLinkListItemStyles = (theme: GrafanaTheme2) => {
return {
wrapper: css({
marginBottom: theme.spacing(2),
@ -95,4 +94,4 @@ const getDataLinkListItemStyles = stylesFactory((theme: GrafanaTheme2) => {
maxWidth: '90%',
}),
};
});
};

@ -4,7 +4,7 @@ import React, { PureComponent } from 'react';
import { DataSourceSettings } from '@grafana/data';
import { stylesFactory } from '../../themes';
import { useStyles2 } from '../../themes';
import { Button } from '../Button';
import { FormField } from '../FormField/FormField';
import { Icon } from '../Icon/Icon';
@ -36,8 +36,7 @@ interface CustomHeaderRowProps {
onBlur: () => void;
}
const getCustomHeaderRowStyles = stylesFactory(() => {
return {
const getCustomHeaderRowStyles = () => ({
layout: css({
display: 'flex',
alignItems: 'center',
@ -51,11 +50,11 @@ const getCustomHeaderRowStyles = stylesFactory(() => {
},
},
}),
};
});
const CustomHeaderRow = ({ header, onBlur, onChange, onRemove, onReset }: CustomHeaderRowProps) => {
const styles = getCustomHeaderRowStyles();
const styles = useStyles2(getCustomHeaderRowStyles);
return (
<div className={styles.layout}>
<FormField

@ -72,7 +72,7 @@ export const DateTimePicker = ({
const { dialogProps } = useDialog({}, ref);
const theme = useTheme2();
const { modalBackdrop } = getModalStyles(theme);
const { modalBackdrop } = useStyles2(getModalStyles);
const isFullscreen = useMedia(`(min-width: ${theme.breakpoints.values.lg}px)`);
const styles = useStyles2(getStyles);

@ -4,8 +4,7 @@ import React, { FormEvent, MouseEvent, useState } from 'react';
import { dateTime, getDefaultTimeRange, GrafanaTheme2, TimeRange, TimeZone } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { stylesFactory } from '../../themes';
import { useTheme2 } from '../../themes/ThemeContext';
import { useStyles2 } from '../../themes/ThemeContext';
import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper';
import { Icon } from '../Icon/Icon';
import { getInputStyles } from '../Input/Input';
@ -47,8 +46,7 @@ export const TimeRangeInput = ({
showIcon = false,
}: TimeRangeInputProps) => {
const [isOpen, setIsOpen] = useState(false);
const theme = useTheme2();
const styles = getStyles(theme, disabled);
const styles = useStyles2(getStyles, disabled);
const onOpen = (event: FormEvent<HTMLButtonElement>) => {
event.stopPropagation();
@ -115,7 +113,7 @@ export const TimeRangeInput = ({
);
};
const getStyles = stylesFactory((theme: GrafanaTheme2, disabled = false) => {
const getStyles = (theme: GrafanaTheme2, disabled = false) => {
const inputStyles = getInputStyles({ theme, invalid: false });
return {
container: css({
@ -163,4 +161,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, disabled = false) => {
marginRight: theme.spacing(0.5),
}),
};
});
};

@ -16,7 +16,7 @@ import {
} from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useStyles2, useTheme2 } from '../../themes/ThemeContext';
import { useStyles2 } from '../../themes/ThemeContext';
import { t, Trans } from '../../utils/i18n';
import { ButtonGroup } from '../Button';
import { getModalStyles } from '../Modal/getModalStyles';
@ -106,9 +106,8 @@ export function TimeRangePicker(props: TimeRangePickerProps) {
);
const { dialogProps } = useDialog({}, overlayRef);
const theme = useTheme2();
const styles = useStyles2(getStyles);
const { modalBackdrop } = getModalStyles(theme);
const { modalBackdrop } = useStyles2(getModalStyles);
const hasAbsolute = isDateTime(value.raw.from) || isDateTime(value.raw.to);
const variant = isSynced ? 'active' : isOnCanvas ? 'canvas' : 'default';

@ -7,7 +7,7 @@ import React, { FormEvent, memo } from 'react';
import { DateTime, GrafanaTheme2, TimeZone } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useTheme2 } from '../../../themes';
import { useStyles2, useTheme2 } from '../../../themes';
import { getModalStyles } from '../../Modal/getModalStyles';
import { Body } from './CalendarBody';
@ -68,7 +68,7 @@ export interface TimePickerCalendarProps {
function TimePickerCalendar(props: TimePickerCalendarProps) {
const theme = useTheme2();
const { modalBackdrop } = getModalStyles(theme);
const { modalBackdrop } = useStyles2(getModalStyles);
const styles = getStyles(theme, props.isReversed);
const { isOpen, isFullscreen, onClose } = props;
const ref = React.createRef<HTMLElement>();

@ -4,7 +4,7 @@ import React, { memo, useMemo, useState } from 'react';
import { GrafanaTheme2, isDateTime, rangeUtil, RawTimeRange, TimeOption, TimeRange, TimeZone } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { stylesFactory, useTheme2 } from '../../../themes';
import { useStyles2, useTheme2 } from '../../../themes';
import { getFocusStyles } from '../../../themes/mixins';
import { t, Trans } from '../../../utils/i18n';
import { CustomScrollbar } from '../../CustomScrollbar/CustomScrollbar';
@ -63,8 +63,7 @@ export const TimePickerContentWithScreenSize = (props: PropsWithScreenSize) => {
const isHistoryEmpty = !history?.length;
const isContainerTall =
(isFullscreen && showHistory) || (!isFullscreen && ((showHistory && !isHistoryEmpty) || !hideQuickRanges));
const theme = useTheme2();
const styles = getStyles(theme, isReversed, hideQuickRanges, isContainerTall, isFullscreen);
const styles = useStyles2(getStyles, isReversed, hideQuickRanges, isContainerTall, isFullscreen);
const historyOptions = mapToHistoryOptions(history, timeZone);
const timeOption = useTimeOption(value.raw, quickOptions);
const [searchTerm, setSearchQuery] = useState('');
@ -124,8 +123,7 @@ export const TimePickerContent = (props: Props) => {
const NarrowScreenForm = (props: FormProps) => {
const { value, hideQuickRanges, onChange, timeZone, historyOptions = [], showHistory } = props;
const theme = useTheme2();
const styles = getNarrowScreenStyles(theme);
const styles = useStyles2(getNarrowScreenStyles);
const isAbsolute = isDateTime(value.raw.from) || isDateTime(value.raw.to);
const [collapsedFlag, setCollapsedFlag] = useState(!isAbsolute);
const collapsed = hideQuickRanges ? false : collapsedFlag;
@ -176,8 +174,7 @@ const NarrowScreenForm = (props: FormProps) => {
const FullScreenForm = (props: FormProps) => {
const { onChange, value, timeZone, fiscalYearStartMonth, isReversed, historyOptions } = props;
const theme = useTheme2();
const styles = getFullScreenStyles(theme, props.hideQuickRanges);
const styles = useStyles2(getFullScreenStyles, props.hideQuickRanges);
const onChangeTimeOption = (timeOption: TimeOption) => {
return onChange(mapOptionToTimeRange(timeOption, timeZone));
};
@ -214,8 +211,7 @@ const FullScreenForm = (props: FormProps) => {
};
const EmptyRecentList = memo(() => {
const theme = useTheme2();
const styles = getEmptyListStyles(theme);
const styles = useStyles2(getEmptyListStyles);
const emptyRecentListText = t(
'time-picker.content.empty-recent-list-info',
"It looks like you haven't used this time picker before. As soon as you enter some time intervals, recently used intervals will appear here."
@ -263,8 +259,13 @@ const useTimeOption = (raw: RawTimeRange, quickOptions: TimeOption[]): TimeOptio
}, [raw, quickOptions]);
};
const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRanges, isContainerTall, isFullscreen) => {
return {
const getStyles = (
theme: GrafanaTheme2,
isReversed?: boolean,
hideQuickRanges?: boolean,
isContainerTall?: boolean,
isFullscreen?: boolean
) => ({
container: css({
background: theme.colors.background.primary,
boxShadow: theme.shadows.z3,
@ -299,11 +300,9 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRang
spacing: css({
marginTop: '16px',
}),
};
});
const getNarrowScreenStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getNarrowScreenStyles = (theme: GrafanaTheme2) => ({
header: css({
display: 'flex',
flexDirection: 'row',
@ -326,11 +325,9 @@ const getNarrowScreenStyles = stylesFactory((theme: GrafanaTheme2) => {
form: css({
padding: '7px 9px 7px 9px',
}),
};
});
const getFullScreenStyles = stylesFactory((theme: GrafanaTheme2, hideQuickRanges?: boolean) => {
return {
const getFullScreenStyles = (theme: GrafanaTheme2, hideQuickRanges?: boolean) => ({
container: css({
paddingTop: '9px',
paddingLeft: '11px',
@ -346,11 +343,9 @@ const getFullScreenStyles = stylesFactory((theme: GrafanaTheme2, hideQuickRanges
justifyContent: 'flex-end',
paddingTop: theme.spacing(1),
}),
};
});
const getEmptyListStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getEmptyListStyles = (theme: GrafanaTheme2) => ({
container: css({
padding: '12px',
margin: '12px',
@ -362,5 +357,4 @@ const getEmptyListStyles = stylesFactory((theme: GrafanaTheme2) => {
link: css({
color: theme.colors.text.link,
}),
};
});

@ -5,7 +5,7 @@ import React, { useCallback, useState } from 'react';
import { getTimeZoneInfo, GrafanaTheme2, TimeZone } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { stylesFactory, useTheme2 } from '../../../themes';
import { useStyles2 } from '../../../themes';
import { t, Trans } from '../../../utils/i18n';
import { Button } from '../../Button';
import { Field } from '../../Forms/Field';
@ -46,8 +46,7 @@ export const TimePickerFooter = (props: Props) => {
[isEditing, setEditing]
);
const theme = useTheme2();
const style = getStyle(theme);
const style = useStyles2(getStyle);
if (!isString(timeZone)) {
return null;
@ -136,8 +135,7 @@ export const TimePickerFooter = (props: Props) => {
);
};
const getStyle = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyle = (theme: GrafanaTheme2) => ({
container: css({
borderTop: `1px solid ${theme.colors.border.weak}`,
padding: '11px',
@ -174,5 +172,4 @@ const getStyle = stylesFactory((theme: GrafanaTheme2) => {
alignItems: 'baseline',
flexGrow: 1,
}),
};
});

@ -3,32 +3,12 @@ import React, { ReactNode } from 'react';
import { TimeOption } from '@grafana/data';
import { stylesFactory } from '../../../themes';
import { useStyles2 } from '../../../themes';
import { t } from '../../../utils/i18n';
import { TimePickerTitle } from './TimePickerTitle';
import { TimeRangeOption } from './TimeRangeOption';
const getStyles = stylesFactory(() => {
return {
title: css({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '8px 16px 5px 9px',
}),
};
});
const getOptionsStyles = stylesFactory(() => {
return {
grow: css({
flexGrow: 1,
alignItems: 'flex-start',
}),
};
});
interface Props {
title?: string;
options: TimeOption[];
@ -38,7 +18,7 @@ interface Props {
}
export const TimeRangeList = (props: Props) => {
const styles = getStyles();
const styles = useStyles2(getStyles);
const { title, options, placeholderEmpty } = props;
if (typeof placeholderEmpty !== 'undefined' && options.length <= 0) {
@ -62,7 +42,7 @@ export const TimeRangeList = (props: Props) => {
};
const Options = ({ options, value, onChange, title }: Props) => {
const styles = getOptionsStyles();
const styles = useStyles2(getOptionsStyles);
return (
<>
@ -92,3 +72,19 @@ function isEqual(x: TimeOption, y?: TimeOption): boolean {
}
return y.from === x.from && y.to === x.to;
}
const getStyles = () => ({
title: css({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '8px 16px 5px 9px',
}),
});
const getOptionsStyles = () => ({
grow: css({
flexGrow: 1,
alignItems: 'flex-start',
}),
});

@ -4,8 +4,7 @@ import React, { PropsWithChildren, RefCallback } from 'react';
import { GrafanaTheme2, SelectableValue, getTimeZoneInfo } from '@grafana/data';
import { useTheme2 } from '../../../themes/ThemeContext';
import { stylesFactory } from '../../../themes/stylesFactory';
import { useStyles2 } from '../../../themes';
import { Icon } from '../../Icon/Icon';
import { TimeZoneDescription } from './TimeZoneDescription';
@ -28,8 +27,7 @@ export interface SelectableZone extends SelectableValue<string> {
export const WideTimeZoneOption = (props: PropsWithChildren<Props>) => {
const { children, innerProps, innerRef, data, isSelected, isFocused } = props;
const theme = useTheme2();
const styles = getStyles(theme);
const styles = useStyles2(getStyles);
const timestamp = Date.now();
const containerStyles = cx(styles.container, isFocused && styles.containerFocused);
@ -68,8 +66,7 @@ export const WideTimeZoneOption = (props: PropsWithChildren<Props>) => {
export const CompactTimeZoneOption = (props: React.PropsWithChildren<Props>) => {
const { children, innerProps, innerRef, data, isSelected, isFocused } = props;
const theme = useTheme2();
const styles = getStyles(theme);
const styles = useStyles2(getStyles);
const timestamp = Date.now();
const containerStyles = cx(styles.container, isFocused && styles.containerFocused);
@ -113,8 +110,7 @@ export const CompactTimeZoneOption = (props: React.PropsWithChildren<Props>) =>
);
};
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyles = (theme: GrafanaTheme2) => ({
container: css({
display: 'flex',
alignItems: 'center',
@ -157,5 +153,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
spacer: css({
marginLeft: '6px',
}),
};
});

@ -1,23 +1,19 @@
import { css } from '@emotion/css';
import React from 'react';
import { stylesFactory } from '../../themes';
import { useStyles2 } from '../../themes';
import { ErrorBoundaryApi } from './ErrorBoundary';
const getStyles = stylesFactory(() => {
return css({
width: '500px',
margin: '64px auto',
});
});
export interface Props extends ErrorBoundaryApi {
title: string;
}
export const ErrorWithStack = ({ error, errorInfo, title }: Props) => (
<div className={getStyles()}>
export const ErrorWithStack = ({ error, errorInfo, title }: Props) => {
const style = useStyles2(getStyles);
return (
<div className={style}>
<h2>{title}</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
{error && error.toString()}
@ -25,6 +21,14 @@ export const ErrorWithStack = ({ error, errorInfo, title }: Props) => (
{errorInfo && errorInfo.componentStack}
</details>
</div>
);
);
};
ErrorWithStack.displayName = 'ErrorWithStack';
const getStyles = () => {
return css({
width: '500px',
margin: '64px auto',
});
};

@ -3,7 +3,7 @@ import React, { HTMLProps, useCallback } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
import { getLabelStyles } from './Label';
@ -36,8 +36,7 @@ export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
},
[onChange]
);
const theme = useTheme2();
const styles = getCheckboxStyles(theme, invalid);
const styles = useStyles2(getCheckboxStyles, invalid);
const ariaChecked = indeterminate ? 'mixed' : undefined;

@ -3,7 +3,7 @@ import React, { HTMLAttributes } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { getChildId } from '../../utils/reactUtils';
import { FieldValidationMessage } from './FieldValidationMessage';
@ -40,35 +40,6 @@ export interface FieldProps extends HTMLAttributes<HTMLDivElement> {
htmlFor?: string;
}
export const getFieldStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
field: css({
display: 'flex',
flexDirection: 'column',
marginBottom: theme.spacing(2),
}),
fieldHorizontal: css({
flexDirection: 'row',
justifyContent: 'space-between',
flexWrap: 'wrap',
}),
fieldValidationWrapper: css({
marginTop: theme.spacing(0.5),
}),
fieldValidationWrapperHorizontal: css({
flex: '1 1 100%',
}),
validationMessageHorizontalOverflow: css({
width: 0,
overflowX: 'visible',
'& > *': {
whiteSpace: 'nowrap',
},
}),
};
});
export const Field = React.forwardRef<HTMLDivElement, FieldProps>(
(
{
@ -88,8 +59,7 @@ export const Field = React.forwardRef<HTMLDivElement, FieldProps>(
}: FieldProps,
ref
) => {
const theme = useTheme2();
const styles = getFieldStyles(theme);
const styles = useStyles2(getFieldStyles);
const inputId = htmlFor ?? getChildId(children);
const labelElement =
@ -143,3 +113,30 @@ function deleteUndefinedProps<T extends Object>(obj: T): Partial<T> {
return obj;
}
export const getFieldStyles = (theme: GrafanaTheme2) => ({
field: css({
display: 'flex',
flexDirection: 'column',
marginBottom: theme.spacing(2),
}),
fieldHorizontal: css({
flexDirection: 'row',
justifyContent: 'space-between',
flexWrap: 'wrap',
}),
fieldValidationWrapper: css({
marginTop: theme.spacing(0.5),
}),
fieldValidationWrapperHorizontal: css({
flex: '1 1 100%',
}),
validationMessageHorizontalOverflow: css({
width: 0,
overflowX: 'visible',
'& > *': {
whiteSpace: 'nowrap',
},
}),
});

@ -3,7 +3,7 @@ import React, { HTMLProps } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { Legend } from './Legend';
@ -14,8 +14,7 @@ export interface Props extends Omit<HTMLProps<HTMLFieldSetElement>, 'label'> {
}
export const FieldSet = ({ label, children, className, ...rest }: Props) => {
const theme = useTheme2();
const styles = getStyles(theme);
const styles = useStyles2(getStyles);
return (
<fieldset className={cx(styles.wrapper, className)} {...rest}>
@ -25,8 +24,7 @@ export const FieldSet = ({ label, children, className, ...rest }: Props) => {
);
};
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyles = (theme: GrafanaTheme2) => ({
wrapper: css({
marginBottom: theme.spacing(4),
@ -34,5 +32,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
marginBottom: 0,
},
}),
};
});

@ -3,7 +3,7 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { Icon } from '../Icon/Icon';
export interface FieldValidationMessageProps {
@ -12,7 +12,23 @@ export interface FieldValidationMessageProps {
horizontal?: boolean;
}
export const getFieldValidationMessageStyles = stylesFactory((theme: GrafanaTheme2) => {
export const FieldValidationMessage = ({
children,
horizontal,
className,
}: React.PropsWithChildren<FieldValidationMessageProps>) => {
const styles = useStyles2(getFieldValidationMessageStyles);
const cssName = cx(horizontal ? styles.horizontal : styles.vertical, className);
return (
<div role="alert" className={cssName}>
<Icon className={styles.fieldValidationMessageIcon} name="exclamation-triangle" />
{children}
</div>
);
};
export const getFieldValidationMessageStyles = (theme: GrafanaTheme2) => {
const baseStyle = `
font-size: ${theme.typography.size.sm};
font-weight: ${theme.typography.fontWeightMedium};
@ -69,21 +85,4 @@ export const getFieldValidationMessageStyles = stylesFactory((theme: GrafanaThem
marginRight: theme.spacing(),
}),
};
});
export const FieldValidationMessage = ({
children,
horizontal,
className,
}: React.PropsWithChildren<FieldValidationMessageProps>) => {
const theme = useTheme2();
const styles = getFieldValidationMessageStyles(theme);
const cssName = cx(horizontal ? styles.horizontal : styles.vertical, className);
return (
<div role="alert" className={cssName}>
<Icon className={styles.fieldValidationMessageIcon} name="exclamation-triangle" />
{children}
</div>
);
};

@ -3,7 +3,7 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { useTheme2, stylesFactory } from '../../themes';
import { useStyles2 } from '../../themes';
import { Icon } from '../Icon/Icon';
export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
@ -12,8 +12,31 @@ export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement>
category?: React.ReactNode[];
}
export const getLabelStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
export const Label = ({ children, description, className, category, ...labelProps }: LabelProps) => {
const styles = useStyles2(getLabelStyles);
const categories = category?.map((c, i) => {
return (
<span className={styles.categories} key={`${c}/${i}`}>
<span>{c}</span>
<Icon name="angle-right" className={styles.chevron} />
</span>
);
});
return (
<div className={cx(styles.label, className)}>
<label {...labelProps}>
<div className={styles.labelContent}>
{categories}
{children}
</div>
{description && <span className={styles.description}>{description}</span>}
</label>
</div>
);
};
export const getLabelStyles = (theme: GrafanaTheme2) => ({
label: css({
label: 'Label',
fontSize: theme.typography.size.sm,
@ -43,30 +66,4 @@ export const getLabelStyles = stylesFactory((theme: GrafanaTheme2) => {
chevron: css({
margin: theme.spacing(0, 0.25),
}),
};
});
export const Label = ({ children, description, className, category, ...labelProps }: LabelProps) => {
const theme = useTheme2();
const styles = getLabelStyles(theme);
const categories = category?.map((c, i) => {
return (
<span className={styles.categories} key={`${c}/${i}`}>
<span>{c}</span>
<Icon name="angle-right" className={styles.chevron} />
</span>
);
});
return (
<div className={cx(styles.label, className)}>
<label {...labelProps}>
<div className={styles.labelContent}>
{categories}
{children}
</div>
{description && <span className={styles.description}>{description}</span>}
</label>
</div>
);
};

@ -4,7 +4,7 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { StringSelector } from '@grafana/e2e-selectors';
import { useTheme2, stylesFactory } from '../../../themes';
import { useStyles2 } from '../../../themes';
import { getFocusStyles, getMouseFocusStyles } from '../../../themes/mixins';
import { getPropertiesForButtonSize } from '../commonStyles';
@ -41,8 +41,7 @@ export const RadioButton = React.forwardRef<HTMLInputElement, RadioButtonProps>(
},
ref
) => {
const theme = useTheme2();
const styles = getRadioButtonStyles(theme, size, fullWidth);
const styles = useStyles2(getRadioButtonStyles, size, fullWidth);
return (
<div className={styles.radioOption}>
@ -68,7 +67,7 @@ export const RadioButton = React.forwardRef<HTMLInputElement, RadioButtonProps>(
RadioButton.displayName = 'RadioButton';
const getRadioButtonStyles = stylesFactory((theme: GrafanaTheme2, size: RadioButtonSize, fullWidth?: boolean) => {
const getRadioButtonStyles = (theme: GrafanaTheme2, size: RadioButtonSize, fullWidth?: boolean) => {
const { fontSize, height, padding } = getPropertiesForButtonSize(size, theme);
const textColor = theme.colors.text.secondary;
@ -130,4 +129,4 @@ const getRadioButtonStyles = stylesFactory((theme: GrafanaTheme2, size: RadioBut
},
}),
};
});
};

@ -3,7 +3,7 @@ import React from 'react';
import { GrafanaTheme2, colorManipulator, deprecationWarning } from '@grafana/data';
import { useTheme2, stylesFactory } from '../../themes';
import { useStyles2 } from '../../themes';
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
import { ComponentSize } from '../../types';
import { IconName, IconSize, IconType } from '../../types/icon';
@ -44,8 +44,6 @@ export type Props = BasePropsWithTooltip | BasePropsWithAriaLabel;
export const IconButton = React.forwardRef<HTMLButtonElement, Props>((props, ref) => {
const { size = 'md', variant = 'secondary' } = props;
const theme = useTheme2();
let limitedIconSize: LimitedIconSize;
// very large icons (xl to xxxl) are unified to size xl
@ -56,7 +54,7 @@ export const IconButton = React.forwardRef<HTMLButtonElement, Props>((props, ref
limitedIconSize = size;
}
const styles = getStyles(theme, limitedIconSize, variant);
const styles = useStyles2(getStyles, limitedIconSize, variant);
let ariaLabel: string | undefined;
let buttonRef: typeof ref | undefined;
@ -104,7 +102,7 @@ export const IconButton = React.forwardRef<HTMLButtonElement, Props>((props, ref
IconButton.displayName = 'IconButton';
const getStyles = stylesFactory((theme: GrafanaTheme2, size, variant: IconButtonVariant) => {
const getStyles = (theme: GrafanaTheme2, size: IconSize, variant: IconButtonVariant) => {
// overall size of the IconButton on hover
// theme.spacing.gridSize originates from 2*4px for padding and letting the IconSize generally decide on the hoverSize
const hoverSize = getSvgSize(size) + theme.spacing.gridSize;
@ -166,4 +164,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, size, variant: IconButton
verticalAlign: 'baseline',
}),
};
});
};

@ -3,7 +3,7 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useStyles2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { Alert, AlertVariant } from '../Alert/Alert';
import { Icon } from '../Icon/Icon';
@ -45,11 +45,9 @@ export const InfoBox = React.memo(
InfoBox.displayName = 'InfoBox';
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyles = (theme: GrafanaTheme2) => ({
docsLink: css({
display: 'inline-block',
marginTop: theme.spacing(2),
}),
};
});

@ -4,7 +4,7 @@ import { FocusScope } from '@react-aria/focus';
import { OverlayContainer, useOverlay } from '@react-aria/overlays';
import React, { PropsWithChildren, useRef } from 'react';
import { useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { IconName } from '../../types';
import { t } from '../../utils/i18n';
import { IconButton } from '../IconButton/IconButton';
@ -46,8 +46,7 @@ export function Modal(props: PropsWithChildren<Props>) {
onClickBackdrop,
trapFocus = true,
} = props;
const theme = useTheme2();
const styles = getModalStyles(theme);
const styles = useStyles2(getModalStyles);
const ref = useRef<HTMLDivElement>(null);
@ -101,8 +100,7 @@ export function Modal(props: PropsWithChildren<Props>) {
}
function ModalButtonRow({ leftItems, children }: { leftItems?: React.ReactNode; children: React.ReactNode }) {
const theme = useTheme2();
const styles = getModalStyles(theme);
const styles = useStyles2(getModalStyles);
if (leftItems) {
return (

@ -2,9 +2,7 @@ import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory } from '../../themes';
export const getModalStyles = stylesFactory((theme: GrafanaTheme2) => {
export const getModalStyles = (theme: GrafanaTheme2) => {
const borderRadius = theme.shape.radius.default;
return {
@ -80,4 +78,4 @@ export const getModalStyles = stylesFactory((theme: GrafanaTheme2) => {
paddingTop: theme.spacing(3),
}),
};
});
};

@ -3,8 +3,7 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory } from '../../themes';
import { useTheme2 } from '../../themes/ThemeContext';
import { useStyles2 } from '../../themes/ThemeContext';
import { inputPadding } from '../Forms/commonStyles';
import { getInputStyles } from '../Input/Input';
@ -17,7 +16,20 @@ interface InputControlProps {
innerProps: JSX.IntrinsicElements['div'];
}
const getInputControlStyles = stylesFactory((theme: GrafanaTheme2, invalid: boolean, withPrefix: boolean) => {
export const InputControl = React.forwardRef<HTMLDivElement, React.PropsWithChildren<InputControlProps>>(
function InputControl({ focused, invalid, disabled, children, innerProps, prefix, ...otherProps }, ref) {
const styles = useStyles2(getInputControlStyles, invalid, !!prefix);
return (
<div className={styles.input} {...innerProps} ref={ref}>
{prefix && <div className={cx(styles.prefix)}>{prefix}</div>}
{children}
</div>
);
}
);
const getInputControlStyles = (theme: GrafanaTheme2, invalid: boolean, withPrefix: boolean) => {
const styles = getInputStyles({ theme, invalid });
return {
@ -47,17 +59,4 @@ const getInputControlStyles = stylesFactory((theme: GrafanaTheme2, invalid: bool
})
),
};
});
export const InputControl = React.forwardRef<HTMLDivElement, React.PropsWithChildren<InputControlProps>>(
function InputControl({ focused, invalid, disabled, children, innerProps, prefix, ...otherProps }, ref) {
const theme = useTheme2();
const styles = getInputControlStyles(theme, invalid, !!prefix);
return (
<div className={styles.input} {...innerProps} ref={ref}>
{prefix && <div className={cx(styles.prefix)}>{prefix}</div>}
{children}
</div>
);
}
);
};

@ -4,8 +4,7 @@ import { components, ContainerProps as BaseContainerProps, GroupBase } from 'rea
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory } from '../../themes';
import { useTheme2 } from '../../themes/ThemeContext';
import { useStyles2 } from '../../themes/ThemeContext';
import { getFocusStyles } from '../../themes/mixins';
import { sharedInputStyle } from '../Forms/commonStyles';
import { getInputStyles } from '../Input/Input';
@ -26,8 +25,7 @@ export const SelectContainer = <Option, isMulti extends boolean, Group extends G
selectProps: { invalid = false },
} = props;
const theme = useTheme2();
const styles = getSelectContainerStyles(theme, isFocused, isDisabled, invalid);
const styles = useStyles2(getSelectContainerStyles, isFocused, isDisabled, invalid);
return (
<components.SelectContainer {...props} className={cx(styles.wrapper, props.className)}>
@ -36,8 +34,7 @@ export const SelectContainer = <Option, isMulti extends boolean, Group extends G
);
};
const getSelectContainerStyles = stylesFactory(
(theme: GrafanaTheme2, focused: boolean, disabled: boolean, invalid: boolean) => {
const getSelectContainerStyles = (theme: GrafanaTheme2, focused: boolean, disabled: boolean, invalid: boolean) => {
const styles = getInputStyles({ theme, invalid });
return {
@ -64,5 +61,4 @@ const getSelectContainerStyles = stylesFactory(
})
),
};
}
);
};

@ -3,7 +3,7 @@ import { Global } from '@emotion/react';
import Slider, { SliderProps } from 'rc-slider';
import React, { useCallback } from 'react';
import { useTheme2 } from '../../themes/ThemeContext';
import { useStyles2 } from '../../themes/ThemeContext';
import HandleTooltip from './HandleTooltip';
import { getStyles } from './styles';
@ -43,8 +43,7 @@ export const RangeSlider = ({
);
const isHorizontal = orientation === 'horizontal';
const theme = useTheme2();
const styles = getStyles(theme, isHorizontal);
const styles = useStyles2(getStyles, isHorizontal);
const tipHandleRender: SliderProps['handleRender'] = (node, handleProps) => {
return (

@ -3,7 +3,7 @@ import { Global } from '@emotion/react';
import SliderComponent from 'rc-slider';
import React, { useState, useCallback, ChangeEvent, FocusEvent } from 'react';
import { useTheme2 } from '../../themes/ThemeContext';
import { useStyles2 } from '../../themes/ThemeContext';
import { Input } from '../Input/Input';
import { getStyles } from './styles';
@ -26,8 +26,7 @@ export const Slider = ({
included,
}: SliderProps) => {
const isHorizontal = orientation === 'horizontal';
const theme = useTheme2();
const styles = getStyles(theme, isHorizontal, Boolean(marks));
const styles = useStyles2(getStyles, isHorizontal, Boolean(marks));
const SliderWithTooltip = SliderComponent;
const [sliderValue, setSliderValue] = useState<number>(value ?? min);

@ -3,9 +3,7 @@ import { css as cssCore } from '@emotion/react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory } from '../../themes';
export const getStyles = stylesFactory((theme: GrafanaTheme2, isHorizontal: boolean, hasMarks = false) => {
export const getStyles = (theme: GrafanaTheme2, isHorizontal: boolean, hasMarks = false) => {
const { spacing } = theme;
const railColor = theme.colors.border.strong;
const trackColor = theme.colors.primary.main;
@ -127,4 +125,4 @@ export const getStyles = stylesFactory((theme: GrafanaTheme2, isHorizontal: bool
order: 1,
}),
};
});
};

@ -4,7 +4,7 @@ import React, { HTMLProps, useRef } from 'react';
import { GrafanaTheme2, deprecationWarning } from '@grafana/data';
import { stylesFactory, useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
export interface Props extends Omit<HTMLProps<HTMLInputElement>, 'value'> {
@ -21,8 +21,7 @@ export const Switch = React.forwardRef<HTMLInputElement, Props>(
deprecationWarning('Switch', 'checked prop', 'value');
}
const theme = useTheme2();
const styles = getSwitchStyles(theme);
const styles = useStyles2(getSwitchStyles);
const switchIdRef = useRef(id ? id : uniqueId('switch-'));
return (
@ -52,8 +51,7 @@ export interface InlineSwitchProps extends Props {
export const InlineSwitch = React.forwardRef<HTMLInputElement, InlineSwitchProps>(
({ transparent, className, showLabel, label, value, id, invalid, ...props }, ref) => {
const theme = useTheme2();
const styles = getSwitchStyles(theme, transparent);
const styles = useStyles2(getSwitchStyles, transparent);
return (
<div
@ -75,8 +73,7 @@ export const InlineSwitch = React.forwardRef<HTMLInputElement, InlineSwitchProps
InlineSwitch.displayName = 'Switch';
const getSwitchStyles = stylesFactory((theme: GrafanaTheme2, transparent?: boolean) => {
return {
const getSwitchStyles = (theme: GrafanaTheme2, transparent?: boolean) => ({
switch: css({
width: '32px',
height: '16px',
@ -180,5 +177,4 @@ const getSwitchStyles = stylesFactory((theme: GrafanaTheme2, transparent?: boole
border: `1px solid ${theme.colors.error.border}`,
},
}),
};
});

@ -5,7 +5,7 @@ import { SelectableValue, GrafanaTheme2 } from '@grafana/data';
import { IconButton } from '../../components/IconButton/IconButton';
import { TabsBar, Tab, TabContent } from '../../components/Tabs';
import { stylesFactory, useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { IconName } from '../../types/icon';
import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar';
@ -23,45 +23,14 @@ export interface TabbedContainerProps {
onClose: () => void;
}
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
container: css({
height: '100%',
}),
tabContent: css({
padding: theme.spacing(2),
backgroundColor: theme.colors.background.primary,
height: `calc(100% - ${theme.components.menuTabs.height}px)`,
}),
close: css({
position: 'absolute',
right: '16px',
top: '5px',
cursor: 'pointer',
fontSize: theme.typography.size.lg,
}),
tabs: css({
paddingTop: theme.spacing(1),
borderColor: theme.colors.border.weak,
ul: {
marginLeft: theme.spacing(2),
},
}),
};
});
export function TabbedContainer(props: TabbedContainerProps) {
const [activeTab, setActiveTab] = useState(
props.tabs.some((tab) => tab.value === props.defaultTab) ? props.defaultTab : props.tabs?.[0].value
);
export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose }: TabbedContainerProps) {
const [activeTab, setActiveTab] = useState(tabs.some((tab) => tab.value === defaultTab) ? defaultTab : tabs[0].value);
const onSelectTab = (item: SelectableValue<string>) => {
setActiveTab(item.value!);
};
const { tabs, onClose, closeIconTooltip } = props;
const theme = useTheme2();
const styles = getStyles(theme);
const styles = useStyles2(getStyles);
return (
<div className={styles.container}>
@ -83,3 +52,28 @@ export function TabbedContainer(props: TabbedContainerProps) {
</div>
);
}
const getStyles = (theme: GrafanaTheme2) => ({
container: css({
height: '100%',
}),
tabContent: css({
padding: theme.spacing(2),
backgroundColor: theme.colors.background.primary,
height: `calc(100% - ${theme.components.menuTabs.height}px)`,
}),
close: css({
position: 'absolute',
right: '16px',
top: '5px',
cursor: 'pointer',
fontSize: theme.typography.size.lg,
}),
tabs: css({
paddingTop: theme.spacing(1),
borderColor: theme.colors.border.weak,
ul: {
marginLeft: theme.spacing(2),
},
}),
});

@ -5,7 +5,7 @@ import { FixedSizeList as List } from 'react-window';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Checkbox, FilterInput, Label, VerticalGroup } from '..';
import { stylesFactory, useTheme2 } from '../../themes';
import { useStyles2, useTheme2 } from '../../themes';
interface Props {
values: SelectableValue[];
@ -18,8 +18,6 @@ const ITEM_HEIGHT = 28;
const MIN_HEIGHT = ITEM_HEIGHT * 5;
export const FilterList = ({ options, values, caseSensitive, onChange }: Props) => {
const theme = useTheme2();
const styles = getStyles(theme);
const [searchFilter, setSearchFilter] = useState('');
const regex = useMemo(() => new RegExp(searchFilter, caseSensitive ? undefined : 'i'), [searchFilter, caseSensitive]);
const items = useMemo(
@ -32,16 +30,12 @@ export const FilterList = ({ options, values, caseSensitive, onChange }: Props)
}),
[options, regex]
);
const styles = useStyles2(getStyles);
const theme = useTheme2();
const gutter = theme.spacing.gridSize;
const height = useMemo(() => Math.min(items.length * ITEM_HEIGHT, MIN_HEIGHT) + gutter, [gutter, items.length]);
const onInputChange = useCallback(
(v: string) => {
setSearchFilter(v);
},
[setSearchFilter]
);
const onCheckedChanged = useCallback(
(option: SelectableValue) => (event: React.FormEvent<HTMLInputElement>) => {
const newValues = event.currentTarget.checked
@ -55,7 +49,7 @@ export const FilterList = ({ options, values, caseSensitive, onChange }: Props)
return (
<VerticalGroup spacing="md">
<FilterInput placeholder="Filter values" onChange={onInputChange} value={searchFilter} />
<FilterInput placeholder="Filter values" onChange={setSearchFilter} value={searchFilter} />
{!items.length && <Label>No values</Label>}
{items.length && (
<List
@ -82,7 +76,7 @@ export const FilterList = ({ options, values, caseSensitive, onChange }: Props)
);
};
const getStyles = stylesFactory((theme: GrafanaTheme2) => ({
const getStyles = (theme: GrafanaTheme2) => ({
filterList: css({
label: 'filterList',
}),
@ -98,4 +92,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => ({
backgroundColor: theme.colors.action.hover,
},
}),
}));
});

@ -3,10 +3,19 @@ import React from 'react';
import { GrafanaTheme2, locale } from '@grafana/data';
import { stylesFactory, useStyles2 } from '../../themes';
import { useStyles2 } from '../../themes';
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
export interface CounterProps {
value: number;
}
export const Counter = ({ value }: CounterProps) => {
const styles = useStyles2(getStyles);
return <span className={styles.counter}>{locale(value, 0).text}</span>;
};
const getStyles = (theme: GrafanaTheme2) => ({
counter: css({
label: 'counter',
marginLeft: theme.spacing(1),
@ -17,15 +26,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
fontWeight: theme.typography.fontWeightMedium,
fontSize: theme.typography.size.sm,
}),
};
});
export interface CounterProps {
value: number;
}
export const Counter = ({ value }: CounterProps) => {
const styles = useStyles2(getStyles);
return <span className={styles.counter}>{locale(value, 0).text}</span>;
};

@ -3,23 +3,14 @@ import React, { HTMLAttributes, ReactNode } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
interface Props extends HTMLAttributes<HTMLDivElement> {
children: ReactNode;
}
const getTabContentStyle = stylesFactory((theme: GrafanaTheme2) => {
return {
tabContent: css({
background: theme.colors.background.primary,
}),
};
});
export const TabContent = ({ children, className, ...restProps }: Props) => {
const theme = useTheme2();
const styles = getTabContentStyle(theme);
const styles = useStyles2(getTabContentStyle);
return (
<div {...restProps} className={cx(styles.tabContent, className)}>
@ -27,3 +18,9 @@ export const TabContent = ({ children, className, ...restProps }: Props) => {
</div>
);
};
const getTabContentStyle = (theme: GrafanaTheme2) => ({
tabContent: css({
background: theme.colors.background.primary,
}),
});

@ -3,7 +3,7 @@ import React, { HTMLProps } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '../../themes';
import { useStyles2 } from '../../themes';
import { getFocusStyle, sharedInputStyle } from '../Forms/commonStyles';
export interface Props extends Omit<HTMLProps<HTMLTextAreaElement>, 'size'> {
@ -12,14 +12,12 @@ export interface Props extends Omit<HTMLProps<HTMLTextAreaElement>, 'size'> {
}
export const TextArea = React.forwardRef<HTMLTextAreaElement, Props>(({ invalid, className, ...props }, ref) => {
const theme = useTheme2();
const styles = getTextAreaStyle(theme, invalid);
const styles = useStyles2(getTextAreaStyle, invalid);
return <textarea {...props} className={cx(styles.textarea, className)} ref={ref} />;
});
const getTextAreaStyle = stylesFactory((theme: GrafanaTheme2, invalid = false) => {
return {
const getTextAreaStyle = (theme: GrafanaTheme2, invalid = false) => ({
textarea: cx(
sharedInputStyle(theme),
getFocusStyle(theme),
@ -31,7 +29,6 @@ const getTextAreaStyle = stylesFactory((theme: GrafanaTheme2, invalid = false) =
borderColor: invalid ? theme.colors.error.border : theme.components.input.borderColor,
})
),
};
});
TextArea.displayName = 'TextArea';

@ -2,10 +2,28 @@ import { css } from '@emotion/css';
import React from 'react';
import { CSSTransition } from 'react-transition-group';
import { stylesFactory } from '../../themes';
import { GrafanaTheme2 } from '@grafana/data';
const getStyles = stylesFactory((duration: number) => {
return {
import { useStyles2 } from '../../themes';
type Props = {
children: React.ReactNode;
visible: boolean;
duration?: number;
};
export function FadeTransition(props: Props) {
const { visible, children, duration = 250 } = props;
const styles = useStyles2(getStyles, duration);
return (
<CSSTransition in={visible} mountOnEnter={true} unmountOnExit={true} timeout={duration} classNames={styles}>
{children}
</CSSTransition>
);
}
const getStyles = (_theme: GrafanaTheme2, duration: number) => ({
enter: css({
label: 'enter',
opacity: 0,
@ -24,21 +42,4 @@ const getStyles = stylesFactory((duration: number) => {
opacity: 0,
transition: `opacity ${duration}ms ease-out`,
}),
};
});
type Props = {
children: React.ReactNode;
visible: boolean;
duration?: number;
};
export function FadeTransition(props: Props) {
const { visible, children, duration = 250 } = props;
const styles = getStyles(duration);
return (
<CSSTransition in={visible} mountOnEnter={true} unmountOnExit={true} timeout={duration} classNames={styles}>
{children}
</CSSTransition>
);
}

@ -2,10 +2,31 @@ import { css } from '@emotion/css';
import React from 'react';
import { CSSTransition } from 'react-transition-group';
import { stylesFactory } from '../../themes';
import { GrafanaTheme2 } from '@grafana/data';
const getStyles = stylesFactory((duration: number, measurement: 'width' | 'height', size: number) => {
return {
import { useStyles2 } from '../../themes';
type Props = {
children: React.ReactNode;
visible: boolean;
size: number;
duration?: number;
horizontal?: boolean;
};
export function SlideOutTransition(props: Props) {
const { visible, children, duration = 250, horizontal, size } = props;
const styles = useStyles2(getStyles, duration, horizontal ? 'width' : 'height', size);
return (
<CSSTransition in={visible} mountOnEnter={true} unmountOnExit={true} timeout={duration} classNames={styles}>
{children}
</CSSTransition>
);
}
const getStyles = (_theme: GrafanaTheme2, duration: number, measurement: 'width' | 'height', size: number) => ({
enter: css({
label: 'enter',
[`${measurement}`]: 0,
@ -28,24 +49,4 @@ const getStyles = stylesFactory((duration: number, measurement: 'width' | 'heigh
[`${measurement}`]: 0,
transition: `opacity ${duration}ms ease-out, ${measurement} ${duration}ms ease-out`,
}),
};
});
type Props = {
children: React.ReactNode;
visible: boolean;
size: number;
duration?: number;
horizontal?: boolean;
};
export function SlideOutTransition(props: Props) {
const { visible, children, duration = 250, horizontal, size } = props;
const styles = getStyles(duration, horizontal ? 'width' : 'height', size);
return (
<CSSTransition in={visible} mountOnEnter={true} unmountOnExit={true} timeout={duration} classNames={styles}>
{children}
</CSSTransition>
);
}

@ -3,13 +3,13 @@
import { css } from '@emotion/css';
import React from 'react';
import { GraphSeriesValue } from '@grafana/data';
import { GrafanaTheme2, GraphSeriesValue } from '@grafana/data';
import { LegendDisplayMode, LegendPlacement } from '@grafana/schema';
import { CustomScrollbar } from '../../components/CustomScrollbar/CustomScrollbar';
import { VizLegend } from '../../components/VizLegend/VizLegend';
import { VizLegendItem } from '../../components/VizLegend/types';
import { stylesFactory } from '../../themes';
import { useStyles2 } from '../../themes';
import { Graph, GraphProps } from './Graph';
@ -25,21 +25,6 @@ export interface GraphWithLegendProps extends GraphProps {
onToggleSort: (sortBy: string) => void;
}
const getGraphWithLegendStyles = stylesFactory(({ placement }: GraphWithLegendProps) => ({
wrapper: css({
display: 'flex',
flexDirection: placement === 'bottom' ? 'column' : 'row',
}),
graphContainer: css({
minHeight: '65%',
flexGrow: 1,
}),
legendContainer: css({
padding: '10px 0',
maxHeight: placement === 'bottom' ? '35%' : 'none',
}),
}));
const shouldHideLegendItem = (data: GraphSeriesValue[][], hideEmpty = false, hideZero = false) => {
const isZeroOnlySeries = data.reduce((acc, current) => acc + (current[1] || 0), 0) === 0;
const isNullOnlySeries = !data.reduce((acc, current) => acc && current[1] !== null, true);
@ -72,7 +57,7 @@ export const GraphWithLegend = (props: GraphWithLegendProps) => {
children,
ariaLabel,
} = props;
const { graphContainer, wrapper, legendContainer } = getGraphWithLegendStyles(props);
const { graphContainer, wrapper, legendContainer } = useStyles2(getGraphWithLegendStyles, props.placement);
const legendItems = series.reduce<VizLegendItem[]>((acc, s) => {
return shouldHideLegendItem(s.data, hideEmpty, hideZero)
@ -130,3 +115,18 @@ export const GraphWithLegend = (props: GraphWithLegendProps) => {
</div>
);
};
const getGraphWithLegendStyles = (_theme: GrafanaTheme2, placement: LegendPlacement) => ({
wrapper: css({
display: 'flex',
flexDirection: placement === 'bottom' ? 'column' : 'row',
}),
graphContainer: css({
minHeight: '65%',
flexGrow: 1,
}),
legendContainer: css({
padding: '10px 0',
maxHeight: placement === 'bottom' ? '35%' : 'none',
}),
});

@ -3,7 +3,7 @@ import React, { ErrorInfo, useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { locationUtil, PageLayoutType } from '@grafana/data';
import { Button, ErrorWithStack, stylesFactory } from '@grafana/ui';
import { Button, ErrorWithStack, useStyles2 } from '@grafana/ui';
import { Page } from '../components/Page/Page';
@ -15,6 +15,7 @@ interface Props {
export function GrafanaRouteError({ error, errorInfo }: Props) {
const location = useLocation();
const isChunkLoadingError = error?.name === 'ChunkLoadError';
const style = useStyles2(getStyles);
useEffect(() => {
// Auto reload page 1 time if we have a chunk load error
@ -27,7 +28,7 @@ export function GrafanaRouteError({ error, errorInfo }: Props) {
return (
<Page navId="error" layout={PageLayoutType.Canvas}>
<div className={getStyles()}>
<div className={style}>
{isChunkLoadingError && (
<div>
<h2>Unable to find application file</h2>
@ -50,9 +51,7 @@ export function GrafanaRouteError({ error, errorInfo }: Props) {
);
}
const getStyles = stylesFactory(() => {
return css`
const getStyles = () => css`
width: 500px;
margin: 64px auto;
`;
});
`;

@ -1,7 +1,7 @@
import { css } from '@emotion/css';
import React from 'react';
import { Modal, stylesFactory } from '@grafana/ui';
import { Modal, useStyles2 } from '@grafana/ui';
import { OnRowOptionsUpdate, RowOptionsForm } from './RowOptionsForm';
@ -14,7 +14,8 @@ export interface RowOptionsModalProps {
}
export const RowOptionsModal = ({ repeat, title, onDismiss, onUpdate, warning }: RowOptionsModalProps) => {
const styles = getStyles();
const styles = useStyles2(getStyles);
return (
<Modal isOpen={true} title="Row options" icon="copy" onDismiss={onDismiss} className={styles.modal}>
<RowOptionsForm repeat={repeat} title={title} onCancel={onDismiss} onUpdate={onUpdate} warning={warning} />
@ -22,11 +23,9 @@ export const RowOptionsModal = ({ repeat, title, onDismiss, onUpdate, warning }:
);
};
const getStyles = stylesFactory(() => {
return {
const getStyles = () => ({
modal: css`
label: RowOptionsModal;
width: 500px;
`,
};
});

@ -4,7 +4,7 @@ import AutoSizer from 'react-virtualized-auto-sizer';
import { areEqual, FixedSizeGrid as Grid } from 'react-window';
import { GrafanaTheme2 } from '@grafana/data';
import { useTheme2, stylesFactory } from '@grafana/ui';
import { useStyles2 } from '@grafana/ui';
import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG';
import { ResourceItem } from './FolderPickerTab';
@ -26,8 +26,7 @@ const MemoizedCell = memo(function Cell(props: CellProps) {
const { cards, columnCount, onChange, selected } = data;
const singleColumnIndex = columnIndex + rowIndex * columnCount;
const card = cards[singleColumnIndex];
const theme = useTheme2();
const styles = getStyles(theme);
const styles = useStyles2(getStyles);
return (
<div style={style}>
@ -56,8 +55,43 @@ const MemoizedCell = memo(function Cell(props: CellProps) {
);
}, areEqual);
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
interface CardProps {
onChange: (value: string) => void;
cards: ResourceItem[];
value?: string;
}
export const ResourceCards = (props: CardProps) => {
const { onChange, cards, value } = props;
const styles = useStyles2(getStyles);
return (
<AutoSizer defaultWidth={680}>
{({ width, height }) => {
const cardWidth = 90;
const cardHeight = 90;
const columnCount = Math.floor(width / cardWidth);
const rowCount = Math.ceil(cards.length / columnCount);
return (
<Grid
width={width}
height={height}
columnCount={columnCount}
columnWidth={cardWidth}
rowCount={rowCount}
rowHeight={cardHeight}
itemData={{ cards, columnCount, onChange, selected: value }}
className={styles.grid}
>
{MemoizedCell}
</Grid>
);
}}
</AutoSizer>
);
};
const getStyles = (theme: GrafanaTheme2) => ({
card: css`
display: inline-block;
width: 90px;
@ -100,42 +134,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
grid: css`
border: 1px solid ${theme.colors.border.medium};
`,
};
});
interface CardProps {
onChange: (value: string) => void;
cards: ResourceItem[];
value?: string;
}
export const ResourceCards = (props: CardProps) => {
const { onChange, cards, value } = props;
const theme = useTheme2();
const styles = getStyles(theme);
return (
<AutoSizer defaultWidth={680}>
{({ width, height }) => {
const cardWidth = 90;
const cardHeight = 90;
const columnCount = Math.floor(width / cardWidth);
const rowCount = Math.ceil(cards.length / columnCount);
return (
<Grid
width={width}
height={height}
columnCount={columnCount}
columnWidth={cardWidth}
rowCount={rowCount}
rowHeight={cardHeight}
itemData={{ cards, columnCount, onChange, selected: value }}
className={styles.grid}
>
{MemoizedCell}
</Grid>
);
}}
</AutoSizer>
);
};

@ -5,9 +5,44 @@ import React from 'react';
// Services & Utils
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '@grafana/ui';
import { useStyles2, useTheme2 } from '@grafana/ui';
// Types
export interface Props {
width: number;
children: React.ReactNode;
onResize?: ResizeCallback;
}
export function ExploreDrawer(props: Props) {
const { width, children, onResize } = props;
const theme = useTheme2();
const styles = useStyles2(getStyles);
const drawerWidth = `${width + 31.5}px`;
return (
<Resizable
className={cx(styles.container, styles.drawerActive)}
defaultSize={{ width: drawerWidth, height: `${theme.components.horizontalDrawer.defaultHeight}px` }}
handleClasses={{ top: styles.rzHandle }}
enable={{
top: true,
right: false,
bottom: false,
left: false,
topRight: false,
bottomRight: false,
bottomLeft: false,
topLeft: false,
}}
maxHeight="100vh"
maxWidth={drawerWidth}
minWidth={drawerWidth}
onResize={onResize}
>
{children}
</Resizable>
);
}
const drawerSlide = (theme: GrafanaTheme2) => keyframes`
0% {
@ -19,8 +54,7 @@ const drawerSlide = (theme: GrafanaTheme2) => keyframes`
}
`;
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyles = (theme: GrafanaTheme2) => ({
container: css`
position: fixed !important;
bottom: 0;
@ -48,42 +82,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
background: ${theme.colors.secondary.shade};
}
`,
};
});
export interface Props {
width: number;
children: React.ReactNode;
onResize?: ResizeCallback;
}
export function ExploreDrawer(props: Props) {
const { width, children, onResize } = props;
const theme = useTheme2();
const styles = getStyles(theme);
const drawerWidth = `${width + 31.5}px`;
return (
<Resizable
className={cx(styles.container, styles.drawerActive)}
defaultSize={{ width: drawerWidth, height: `${theme.components.horizontalDrawer.defaultHeight}px` }}
handleClasses={{ top: styles.rzHandle }}
enable={{
top: true,
right: false,
bottom: false,
left: false,
topRight: false,
bottomRight: false,
bottomLeft: false,
topLeft: false,
}}
maxHeight="100vh"
maxWidth={drawerWidth}
minWidth={drawerWidth}
onResize={onResize}
>
{children}
</Resizable>
);
}

@ -1,8 +1,8 @@
import { css } from '@emotion/css';
import React, { useMemo, useState, useEffect } from 'react';
import { StandardEditorProps, SelectableValue, GrafanaTheme2 } from '@grafana/data';
import { Alert, Select, stylesFactory, useTheme2 } from '@grafana/ui';
import { StandardEditorProps, SelectableValue } from '@grafana/data';
import { Alert, Select, useStyles2 } from '@grafana/ui';
import { COUNTRIES_GAZETTEER_PATH, Gazetteer, getGazetteer } from '../gazetteer/gazetteer';
@ -34,7 +34,7 @@ export const GazetteerPathEditor = ({
context,
item,
}: StandardEditorProps<string, GazetteerPathEditorConfigSettings>) => {
const styles = getStyles(useTheme2());
const styles = useStyles2(getStyles);
const [gaz, setGaz] = useState<Gazetteer>();
const settings = item.settings;
@ -86,8 +86,7 @@ export const GazetteerPathEditor = ({
);
};
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyles = () => ({
keys: css`
margin-top: 4px;
text-overflow: ellipsis;
@ -98,5 +97,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
margin-left: 4px;
}
`,
};
});

@ -9,7 +9,7 @@ import {
QueryResultMetaStat,
TimeZone,
} from '@grafana/data';
import { stylesFactory, useTheme2 } from '@grafana/ui';
import { useStyles2, useTheme2 } from '@grafana/ui';
interface InspectStatsTableProps {
timeZone: TimeZone;
@ -19,7 +19,7 @@ interface InspectStatsTableProps {
export const InspectStatsTable = ({ timeZone, name, stats }: InspectStatsTableProps) => {
const theme = useTheme2();
const styles = getStyles(theme);
const styles = useStyles2(getStyles);
if (!stats || !stats.length) {
return null;
@ -56,13 +56,11 @@ function formatStat(stat: QueryResultMetaStat, timeZone: TimeZone, theme: Grafan
return formattedValueToString(display(stat.value));
}
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyles = (theme: GrafanaTheme2) => ({
wrapper: css`
padding-bottom: ${theme.spacing(2)};
`,
cell: css`
text-align: right;
`,
};
});

@ -2,16 +2,15 @@ import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '@grafana/ui';
import { useStyles2 } from '@grafana/ui';
type Props = {
interface Props {
name: string;
traceIds: string[];
};
}
export const InspectStatsTraceIdsTable = ({ name, traceIds }: Props) => {
const theme = useTheme2();
const styles = getStyles(theme);
const styles = useStyles2(getStyles);
if (traceIds.length === 0) {
return null;
@ -35,13 +34,11 @@ export const InspectStatsTraceIdsTable = ({ name, traceIds }: Props) => {
);
};
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyles = (theme: GrafanaTheme2) => ({
wrapper: css`
padding-bottom: ${theme.spacing(2)};
`,
cell: css`
text-align: right;
`,
};
});

@ -3,7 +3,7 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { locationService } from '@grafana/runtime';
import { Button, Modal, stylesFactory, useStyles2 } from '@grafana/ui';
import { Button, Modal, useStyles2 } from '@grafana/ui';
import { dashboardWatcher } from './dashboardWatcher';
import { DashboardEvent, DashboardEventAction } from './types';
@ -50,12 +50,10 @@ export function DashboardChangedModal({ onDismiss, event }: Props) {
);
}
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyles = (theme: GrafanaTheme2) => ({
modal: css({ width: '600px' }),
description: css({
color: theme.colors.text.secondary,
paddingBottom: theme.spacing(1),
}),
};
});

@ -2,7 +2,7 @@ import { css, cx } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Button, InfoBox, Portal, stylesFactory, useTheme2 } from '@grafana/ui';
import { Button, InfoBox, Portal, useStyles2, useTheme2 } from '@grafana/ui';
import { getModalStyles } from '@grafana/ui/src/components/Modal/getModalStyles';
interface Props {
@ -10,9 +10,8 @@ interface Props {
}
export const TokenRevokedModal = (props: Props) => {
const styles = useStyles2(getStyles);
const theme = useTheme2();
const styles = getStyles(theme);
const modalStyles = getModalStyles(theme);
const showMaxConcurrentSessions = Boolean(props.maxConcurrentSessions);
@ -51,8 +50,7 @@ export const TokenRevokedModal = (props: Props) => {
);
};
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
const getStyles = (theme: GrafanaTheme2) => ({
infobox: css`
margin-bottom: 0;
`,
@ -63,5 +61,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
background-color: ${theme.colors.background.canvas};
opacity: 0.8;
`,
};
});

@ -2,7 +2,7 @@ import { css, cx } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, useTheme2 } from '@grafana/ui';
import { useStyles2 } from '@grafana/ui';
export interface SpaceProps {
v?: number;
@ -11,8 +11,7 @@ export interface SpaceProps {
}
export const Space = (props: SpaceProps) => {
const theme = useTheme2();
const styles = getStyles(theme, props);
const styles = useStyles2(getStyles, props);
return <span className={cx(styles.wrapper)} />;
};
@ -23,7 +22,7 @@ Space.defaultProps = {
layout: 'block',
};
const getStyles = stylesFactory((theme: GrafanaTheme2, props: SpaceProps) => ({
const getStyles = (theme: GrafanaTheme2, props: SpaceProps) => ({
wrapper: css([
{
paddingRight: theme.spacing(props.h ?? 0),
@ -36,4 +35,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, props: SpaceProps) => ({
display: 'block',
},
]),
}));
});

@ -3,7 +3,7 @@ import React, { useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { AccessoryButton, InputGroup } from '@grafana/experimental';
import { Input, stylesFactory, useTheme2 } from '@grafana/ui';
import { Input, useStyles2 } from '@grafana/ui';
import { MultiFilterCondition } from './MultiFilter';
@ -17,8 +17,7 @@ export interface Props {
export const MultiFilterItem = ({ filter, onChange, onDelete, keyPlaceholder }: Props) => {
const [localKey, setLocalKey] = useState(filter.key || '');
const [localValue, setLocalValue] = useState(filter.value?.join(', ') || '');
const theme = useTheme2();
const styles = getOperatorStyles(theme);
const styles = useStyles2(getOperatorStyles);
return (
<div data-testid="cloudwatch-multifilter-item">
@ -59,9 +58,9 @@ export const MultiFilterItem = ({ filter, onChange, onDelete, keyPlaceholder }:
);
};
const getOperatorStyles = stylesFactory((theme: GrafanaTheme2) => ({
const getOperatorStyles = (theme: GrafanaTheme2) => ({
root: css({
padding: theme.spacing(0, 1),
alignSelf: 'center',
}),
}));
});

@ -4,7 +4,7 @@ import { useAsyncFn } from 'react-use';
import { GrafanaTheme2, SelectableValue, toOption } from '@grafana/data';
import { AccessoryButton, InputGroup } from '@grafana/experimental';
import { Select, stylesFactory, useTheme2 } from '@grafana/ui';
import { Select, useStyles2 } from '@grafana/ui';
import { CloudWatchDatasource } from '../../../datasource';
import { Dimensions, MetricStat } from '../../../types';
@ -76,8 +76,7 @@ export const FilterItem = ({
metricName,
accountId,
]);
const theme = useTheme2();
const styles = getOperatorStyles(theme);
const styles = useStyles2(getOperatorStyles);
return (
<div data-testid="cloudwatch-dimensions-filter-item">
@ -119,9 +118,9 @@ export const FilterItem = ({
);
};
const getOperatorStyles = stylesFactory((theme: GrafanaTheme2) => ({
const getOperatorStyles = (theme: GrafanaTheme2) => ({
root: css({
padding: theme.spacing(0, 1),
alignSelf: 'center',
}),
}));
});

@ -6,50 +6,28 @@ import { DataSourceInstanceSettings, VariableSuggestion } from '@grafana/data';
import {
Button,
DataLinkInput,
stylesFactory,
InlineField,
InlineSwitch,
InlineFieldRow,
InlineLabel,
Input,
useStyles2,
} from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
import { DataLinkConfig } from '../types';
const getStyles = stylesFactory(() => ({
firstRow: css`
display: flex;
`,
nameField: css`
flex: 2;
`,
regexField: css`
flex: 3;
`,
row: css`
display: flex;
align-items: baseline;
`,
urlField: css`
display: flex;
flex: 1;
`,
urlDisplayLabelField: css`
flex: 1;
`,
}));
type Props = {
interface Props {
value: DataLinkConfig;
onChange: (value: DataLinkConfig) => void;
onDelete: () => void;
suggestions: VariableSuggestion[];
className?: string;
};
}
export const DataLink = (props: Props) => {
const { value, onChange, onDelete, suggestions, className } = props;
const styles = getStyles();
const styles = useStyles2(getStyles);
const [showInternalLink, setShowInternalLink] = useInternalLink(value.datasourceUid);
const handleChange = (field: keyof typeof value) => (event: React.ChangeEvent<HTMLInputElement>) => {
@ -173,3 +151,26 @@ function useInternalLink(datasourceUid?: string): [boolean, Dispatch<SetStateAct
return [showInternalLink, setShowInternalLink];
}
const getStyles = () => ({
firstRow: css`
display: flex;
`,
nameField: css`
flex: 2;
`,
regexField: css`
flex: 3;
`,
row: css`
display: flex;
align-items: baseline;
`,
urlField: css`
display: flex;
flex: 1;
`,
urlDisplayLabelField: css`
flex: 1;
`,
});

@ -2,7 +2,7 @@ import { css } from '@emotion/css';
import React, { ComponentProps } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Field, Icon, PopoverContent, ReactUtils, stylesFactory, Tooltip, useTheme2 } from '@grafana/ui';
import { Field, Icon, PopoverContent, ReactUtils, Tooltip, useStyles2 } from '@grafana/ui';
interface EditorFieldProps extends ComponentProps<typeof Field> {
label: string;
@ -15,8 +15,7 @@ interface EditorFieldProps extends ComponentProps<typeof Field> {
export const EditorField = (props: EditorFieldProps) => {
const { label, optional, tooltip, children, width, ...fieldProps } = props;
const theme = useTheme2();
const styles = getStyles(theme, width);
const styles = useStyles2(getStyles, width);
// Null check for backward compatibility
const childInputId = fieldProps?.htmlFor || ReactUtils?.getChildId(children);
@ -45,8 +44,7 @@ export const EditorField = (props: EditorFieldProps) => {
);
};
const getStyles = stylesFactory((theme: GrafanaTheme2, width?: number | string) => {
return {
const getStyles = (theme: GrafanaTheme2, width?: number | string) => ({
space: css({
paddingRight: theme.spacing(0),
paddingBottom: theme.spacing(0.5),
@ -72,5 +70,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, width?: number | string)
color: theme.colors.text.primary,
},
}),
};
});

Loading…
Cancel
Save