Chore: Avoid explicit React.FC<Props> when possible (round 2) (#64749)

This commit is contained in:
Ryan McKinley 2023-03-15 07:56:09 -07:00 committed by GitHub
parent 1a16636692
commit 4f13e78d11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
147 changed files with 364 additions and 449 deletions

View File

@ -3955,8 +3955,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "2"] [0, 0, 0, "Unexpected any. Specify a different type.", "2"]
], ],
"public/app/features/transformers/FilterByValueTransformer/ValueMatchers/NoopMatcherEditor.tsx:5381": [ "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/NoopMatcherEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "0"]
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
], ],
"public/app/features/transformers/FilterByValueTransformer/ValueMatchers/RangeMatcherEditor.tsx:5381": [ "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/RangeMatcherEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"] [0, 0, 0, "Unexpected any. Specify a different type.", "0"]
@ -3974,9 +3973,6 @@ exports[`better eslint`] = {
"public/app/features/transformers/FilterByValueTransformer/ValueMatchers/valueMatchersUI.ts:5381": [ "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/valueMatchersUI.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"] [0, 0, 0, "Unexpected any. Specify a different type.", "0"]
], ],
"public/app/features/transformers/calculateHeatmap/editor/AxisEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/transformers/calculateHeatmap/editor/helper.ts:5381": [ "public/app/features/transformers/calculateHeatmap/editor/helper.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"] [0, 0, 0, "Unexpected any. Specify a different type.", "0"]
], ],

View File

@ -48,7 +48,7 @@ interface ComponentAProps {
isActive: boolean; isActive: boolean;
} }
const ComponentA: React.FC<ComponentAProps> = ({ isActive }) => { const ComponentA = ({ isActive }: ComponentAProps) => {
const theme = useTheme(); const theme = useTheme();
const styles = useStyles2(theme); const styles = useStyles2(theme);

View File

@ -143,7 +143,7 @@ Let's create a custom query editor to allow the user to edit the query model.
onChange: (query: MyVariableQuery, definition: string) => void; onChange: (query: MyVariableQuery, definition: string) => void;
} }
export const VariableQueryEditor: React.FC<VariableQueryProps> = ({ onChange, query }) => { export const VariableQueryEditor = ({ onChange, query }: VariableQueryProps) => {
const [state, setState] = useState(query); const [state, setState] = useState(query);
const saveQuery = () => { const saveQuery = () => {

View File

@ -17,7 +17,7 @@ import React from 'react';
import { Button } from '@grafana/ui'; import { Button } from '@grafana/ui';
import { StandardEditorProps } from '@grafana/data'; import { StandardEditorProps } from '@grafana/data';
export const SimpleEditor: React.FC<StandardEditorProps<boolean>> = ({ value, onChange }) => { export const SimpleEditor = ({ value, onChange }: StandardEditorProps<boolean>) => {
return <Button onClick={() => onChange(!value)}>{value ? 'Disable' : 'Enable'}</Button>; return <Button onClick={() => onChange(!value)}>{value ? 'Disable' : 'Enable'}</Button>;
}; };
``` ```
@ -51,7 +51,9 @@ interface Settings {
to: number; to: number;
} }
export const SimpleEditor: React.FC<StandardEditorProps<number, Settings>> = ({ item, value, onChange }) => { type Props = StandardEditorProps<number, Settings>;
export const SimpleEditor = ({ item, value, onChange }: Props) => {
const options: Array<SelectableValue<number>> = []; const options: Array<SelectableValue<number>> = [];
// Default values // Default values
@ -97,7 +99,7 @@ The editor context is available through the `context` prop. The data frames retu
**SimpleEditor.tsx** **SimpleEditor.tsx**
```ts ```ts
export const SimpleEditor: React.FC<StandardEditorProps<string>> = ({ item, value, onChange, context }) => { export const SimpleEditor = ({ item, value, onChange, context }: StandardEditorProps<string>) => {
const options: SelectableValue<string>[] = []; const options: SelectableValue<string>[] = [];
if (context.data) { if (context.data) {

View File

@ -44,7 +44,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
}; };
}); });
export const ButtonCascader: React.FC<ButtonCascaderProps> = (props) => { export const ButtonCascader = (props: ButtonCascaderProps) => {
const { onChange, className, loadData, icon, buttonProps, hideDownIcon, variant, disabled, ...rest } = props; const { onChange, className, loadData, icon, buttonProps, hideDownIcon, variant, disabled, ...rest } = props;
const theme = useTheme2(); const theme = useTheme2();
const styles = getStyles(theme); const styles = getStyles(theme);

View File

@ -21,8 +21,8 @@ export interface ContextMenuProps {
renderHeader?: () => React.ReactNode; renderHeader?: () => React.ReactNode;
} }
export const ContextMenu: React.FC<ContextMenuProps> = React.memo( export const ContextMenu = React.memo(
({ x, y, onClose, focusOnOpen = true, renderMenuItems, renderHeader }) => { ({ x, y, onClose, focusOnOpen = true, renderMenuItems, renderHeader }: ContextMenuProps) => {
const menuRef = useRef<HTMLDivElement>(null); const menuRef = useRef<HTMLDivElement>(null);
const [positionStyles, setPositionStyles] = useState({}); const [positionStyles, setPositionStyles] = useState({});

View File

@ -11,7 +11,7 @@ export interface WithContextMenuProps {
focusOnOpen?: boolean; focusOnOpen?: boolean;
} }
export const WithContextMenu: React.FC<WithContextMenuProps> = ({ children, renderMenuItems, focusOnOpen = true }) => { export const WithContextMenu = ({ children, renderMenuItems, focusOnOpen = true }: WithContextMenuProps) => {
const [isMenuOpen, setIsMenuOpen] = useState(false); const [isMenuOpen, setIsMenuOpen] = useState(false);
const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 }); const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 });
return ( return (

View File

@ -30,48 +30,46 @@ const getStyles = (theme: GrafanaTheme2) => ({
`, `,
}); });
export const DataLinkEditor: React.FC<DataLinkEditorProps> = React.memo( export const DataLinkEditor = React.memo(({ index, value, onChange, suggestions, isLast }: DataLinkEditorProps) => {
({ index, value, onChange, suggestions, isLast }) => { const styles = useStyles2(getStyles);
const styles = useStyles2(getStyles);
const onUrlChange = (url: string, callback?: () => void) => { const onUrlChange = (url: string, callback?: () => void) => {
onChange(index, { ...value, url }, callback); onChange(index, { ...value, url }, callback);
}; };
const onTitleChange = (event: ChangeEvent<HTMLInputElement>) => { const onTitleChange = (event: ChangeEvent<HTMLInputElement>) => {
onChange(index, { ...value, title: event.target.value }); onChange(index, { ...value, title: event.target.value });
}; };
const onOpenInNewTabChanged = () => { const onOpenInNewTabChanged = () => {
onChange(index, { ...value, targetBlank: !value.targetBlank }); onChange(index, { ...value, targetBlank: !value.targetBlank });
}; };
return ( return (
<div className={styles.listItem}> <div className={styles.listItem}>
<Field label="Title"> <Field label="Title">
<Input value={value.title} onChange={onTitleChange} placeholder="Show details" /> <Input value={value.title} onChange={onTitleChange} placeholder="Show details" />
</Field> </Field>
<Field <Field
label="URL" label="URL"
invalid={isCompactUrl(value.url)} invalid={isCompactUrl(value.url)}
error="Data link is an Explore URL in a deprecated format. Please visit the URL to be redirected, and edit this data link to use that URL." error="Data link is an Explore URL in a deprecated format. Please visit the URL to be redirected, and edit this data link to use that URL."
> >
<DataLinkInput value={value.url} onChange={onUrlChange} suggestions={suggestions} /> <DataLinkInput value={value.url} onChange={onUrlChange} suggestions={suggestions} />
</Field> </Field>
<Field label="Open in new tab"> <Field label="Open in new tab">
<Switch value={value.targetBlank || false} onChange={onOpenInNewTabChanged} /> <Switch value={value.targetBlank || false} onChange={onOpenInNewTabChanged} />
</Field> </Field>
{isLast && ( {isLast && (
<div className={styles.infoText}> <div className={styles.infoText}>
With data links you can reference data variables like series name, labels and values. Type CMD+Space, With data links you can reference data variables like series name, labels and values. Type CMD+Space,
CTRL+Space, or $ to open variable suggestions. CTRL+Space, or $ to open variable suggestions.
</div> </div>
)} )}
</div> </div>
); );
} });
);
DataLinkEditor.displayName = 'DataLinkEditor'; DataLinkEditor.displayName = 'DataLinkEditor';

View File

@ -72,8 +72,13 @@ const getStyles = (theme: GrafanaTheme2) => ({
// This memoised also because rerendering the slate editor grabs focus which created problem in some cases this // This memoised also because rerendering the slate editor grabs focus which created problem in some cases this
// was used and changes to different state were propagated here. // was used and changes to different state were propagated here.
export const DataLinkInput: React.FC<DataLinkInputProps> = memo( export const DataLinkInput = memo(
({ value, onChange, suggestions, placeholder = 'http://your-grafana.com/d/000000010/annotations' }) => { ({
value,
onChange,
suggestions,
placeholder = 'http://your-grafana.com/d/000000010/annotations',
}: DataLinkInputProps) => {
const editorRef = useRef<Editor>(null); const editorRef = useRef<Editor>(null);
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const [showingSuggestions, setShowingSuggestions] = useState(false); const [showingSuggestions, setShowingSuggestions] = useState(false);

View File

@ -53,7 +53,7 @@ const getStyles = (theme: GrafanaTheme2) => {
}; };
}; };
export const DataLinkSuggestions: React.FC<DataLinkSuggestionsProps> = ({ suggestions, ...otherProps }) => { export const DataLinkSuggestions = ({ suggestions, ...otherProps }: DataLinkSuggestionsProps) => {
const ref = useRef(null); const ref = useRef(null);
useClickAway(ref, () => { useClickAway(ref, () => {
@ -104,8 +104,16 @@ interface DataLinkSuggestionsListProps extends DataLinkSuggestionsProps {
activeRef?: React.RefObject<HTMLDivElement>; activeRef?: React.RefObject<HTMLDivElement>;
} }
const DataLinkSuggestionsList: React.FC<DataLinkSuggestionsListProps> = React.memo( const DataLinkSuggestionsList = React.memo(
({ activeIndex, activeIndexOffset, label, onClose, onSuggestionSelect, suggestions, activeRef: selectedRef }) => { ({
activeIndex,
activeIndexOffset,
label,
onClose,
onSuggestionSelect,
suggestions,
activeRef: selectedRef,
}: DataLinkSuggestionsListProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (

View File

@ -18,12 +18,7 @@ interface DataLinksInlineEditorProps {
data: DataFrame[]; data: DataFrame[];
} }
export const DataLinksInlineEditor: React.FC<DataLinksInlineEditorProps> = ({ export const DataLinksInlineEditor = ({ links, onChange, getSuggestions, data }: DataLinksInlineEditorProps) => {
links,
onChange,
getSuggestions,
data,
}) => {
const theme = useTheme2(); const theme = useTheme2();
const [editIndex, setEditIndex] = useState<number | null>(null); const [editIndex, setEditIndex] = useState<number | null>(null);
const [isNew, setIsNew] = useState(false); const [isNew, setIsNew] = useState(false);

View File

@ -6,7 +6,7 @@ import { SecretFormField } from '../SecretFormField/SecretFormField';
import { HttpSettingsProps } from './types'; import { HttpSettingsProps } from './types';
export const BasicAuthSettings: React.FC<HttpSettingsProps> = ({ dataSourceConfig, onChange }) => { export const BasicAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsProps) => {
const password = dataSourceConfig.secureJsonData ? dataSourceConfig.secureJsonData.basicAuthPassword : ''; const password = dataSourceConfig.secureJsonData ? dataSourceConfig.secureJsonData.basicAuthPassword : '';
const onPasswordReset = () => { const onPasswordReset = () => {

View File

@ -55,7 +55,7 @@ const getCustomHeaderRowStyles = stylesFactory(() => {
}; };
}); });
const CustomHeaderRow: React.FC<CustomHeaderRowProps> = ({ header, onBlur, onChange, onRemove, onReset }) => { const CustomHeaderRow = ({ header, onBlur, onChange, onRemove, onReset }: CustomHeaderRowProps) => {
const styles = getCustomHeaderRowStyles(); const styles = getCustomHeaderRowStyles();
return ( return (
<div className={styles.layout}> <div className={styles.layout}>

View File

@ -61,7 +61,7 @@ const HttpAccessHelp = () => (
const LABEL_WIDTH = 26; const LABEL_WIDTH = 26;
export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => { export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
const { const {
defaultUrl, defaultUrl,
dataSourceConfig, dataSourceConfig,

View File

@ -7,11 +7,11 @@ import { HttpSettingsBaseProps } from './types';
const LABEL_WIDTH = 26; const LABEL_WIDTH = 26;
export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({ export const HttpProxySettings = ({
dataSourceConfig, dataSourceConfig,
onChange, onChange,
showForwardOAuthIdentityOption = true, showForwardOAuthIdentityOption = true,
}) => { }: HttpSettingsBaseProps) => {
return ( return (
<> <>
<div className="gf-form-inline"> <div className="gf-form-inline">

View File

@ -10,7 +10,7 @@ import { Tooltip } from '../Tooltip/Tooltip';
import { CertificationKey } from './CertificationKey'; import { CertificationKey } from './CertificationKey';
import { HttpSettingsBaseProps } from './types'; import { HttpSettingsBaseProps } from './types';
export const TLSAuthSettings: React.FC<HttpSettingsBaseProps> = ({ dataSourceConfig, onChange }) => { export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBaseProps) => {
const hasTLSCACert = dataSourceConfig.secureJsonFields && dataSourceConfig.secureJsonFields.tlsCACert; const hasTLSCACert = dataSourceConfig.secureJsonFields && dataSourceConfig.secureJsonFields.tlsCACert;
const hasTLSClientCert = dataSourceConfig.secureJsonFields && dataSourceConfig.secureJsonFields.tlsClientCert; const hasTLSClientCert = dataSourceConfig.secureJsonFields && dataSourceConfig.secureJsonFields.tlsClientCert;
const hasTLSClientKey = dataSourceConfig.secureJsonFields && dataSourceConfig.secureJsonFields.tlsClientKey; const hasTLSClientKey = dataSourceConfig.secureJsonFields && dataSourceConfig.secureJsonFields.tlsClientKey;

View File

@ -7,7 +7,7 @@ import { RelativeTimeRange } from '@grafana/data';
import { RelativeTimeRangePicker } from './RelativeTimeRangePicker'; import { RelativeTimeRangePicker } from './RelativeTimeRangePicker';
function setup(initial: RelativeTimeRange = { from: 900, to: 0 }): RenderResult { function setup(initial: RelativeTimeRange = { from: 900, to: 0 }): RenderResult {
const StatefulPicker: React.FC<{}> = () => { const StatefulPicker = () => {
const [value, setValue] = useState<RelativeTimeRange>(initial); const [value, setValue] = useState<RelativeTimeRange>(initial);
return <RelativeTimeRangePicker timeRange={value} onChange={setValue} />; return <RelativeTimeRangePicker timeRange={value} onChange={setValue} />;
}; };

View File

@ -43,7 +43,7 @@ interface FormProps extends Omit<Props, 'history'> {
historyOptions?: TimeOption[]; historyOptions?: TimeOption[];
} }
export const TimePickerContentWithScreenSize: React.FC<PropsWithScreenSize> = (props) => { export const TimePickerContentWithScreenSize = (props: PropsWithScreenSize) => {
const { const {
quickOptions = [], quickOptions = [],
isReversed, isReversed,
@ -174,7 +174,7 @@ const NarrowScreenForm = (props: FormProps) => {
); );
}; };
const FullScreenForm: React.FC<FormProps> = (props) => { const FullScreenForm = (props: FormProps) => {
const { onChange, value, timeZone, fiscalYearStartMonth, isReversed, historyOptions } = props; const { onChange, value, timeZone, fiscalYearStartMonth, isReversed, historyOptions } = props;
const theme = useTheme2(); const theme = useTheme2();
const styles = getFullScreenStyles(theme, props.hideQuickRanges); const styles = getFullScreenStyles(theme, props.hideQuickRanges);

View File

@ -26,7 +26,7 @@ export interface SelectableZone extends SelectableValue<string> {
searchIndex: string; searchIndex: string;
} }
export const WideTimeZoneOption: React.FC<PropsWithChildren<Props>> = (props, ref) => { export const WideTimeZoneOption = (props: PropsWithChildren<Props>) => {
const { children, innerProps, innerRef, data, isSelected, isFocused } = props; const { children, innerProps, innerRef, data, isSelected, isFocused } = props;
const theme = useTheme2(); const theme = useTheme2();
const styles = getStyles(theme); const styles = getStyles(theme);
@ -66,7 +66,7 @@ export const WideTimeZoneOption: React.FC<PropsWithChildren<Props>> = (props, re
); );
}; };
export const CompactTimeZoneOption: React.FC<React.PropsWithChildren<Props>> = (props, ref) => { export const CompactTimeZoneOption = (props: React.PropsWithChildren<Props>) => {
const { children, innerProps, innerRef, data, isSelected, isFocused } = props; const { children, innerProps, innerRef, data, isSelected, isFocused } = props;
const theme = useTheme2(); const theme = useTheme2();
const styles = getStyles(theme); const styles = getStyles(theme);

View File

@ -15,7 +15,7 @@ export interface FilterPillProps {
icon?: IconName; icon?: IconName;
} }
export const FilterPill: React.FC<FilterPillProps> = ({ label, selected, onClick, icon = 'check' }) => { export const FilterPill = ({ label, selected, onClick, icon = 'check' }: FilterPillProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const clearButton = useStyles2(clearButtonStyles); const clearButton = useStyles2(clearButtonStyles);
return ( return (

View File

@ -69,7 +69,7 @@ export const getFieldStyles = stylesFactory((theme: GrafanaTheme2) => {
}; };
}); });
export const Field: React.FC<FieldProps> = ({ export const Field = ({
label, label,
description, description,
horizontal, horizontal,
@ -83,7 +83,7 @@ export const Field: React.FC<FieldProps> = ({
validationMessageHorizontalOverflow, validationMessageHorizontalOverflow,
htmlFor, htmlFor,
...otherProps ...otherProps
}) => { }: FieldProps) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = getFieldStyles(theme); const styles = getFieldStyles(theme);
const inputId = htmlFor ?? getChildId(children); const inputId = htmlFor ?? getChildId(children);

View File

@ -46,7 +46,7 @@ export const getLabelStyles = stylesFactory((theme: GrafanaTheme2) => {
}; };
}); });
export const Label: React.FC<LabelProps> = ({ children, description, className, category, ...labelProps }) => { export const Label = ({ children, description, className, category, ...labelProps }: LabelProps) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = getLabelStyles(theme); const styles = getLabelStyles(theme);
const categories = category?.map((c, i) => { const categories = category?.map((c, i) => {

View File

@ -20,7 +20,7 @@ export const getLegendStyles = (theme: GrafanaTheme2) => {
}; };
}; };
export const Legend: React.FC<LabelProps> = ({ children, className, ...legendProps }) => { export const Legend = ({ children, className, ...legendProps }: LabelProps) => {
const styles = useStyles2(getLegendStyles); const styles = useStyles2(getLegendStyles);
return ( return (

View File

@ -115,7 +115,7 @@ DisabledList.args = {
}; };
export const Dots: Story = () => { export const Dots: Story = () => {
const Wrapper: React.FC<React.PropsWithChildren<{ title: string }>> = ({ title, children }) => ( const Wrapper = ({ title, children }: React.PropsWithChildren<{ title: string }>) => (
<div style={{ marginBottom: 20 }}> <div style={{ marginBottom: 20 }}>
<h5>{title}</h5> <h5>{title}</h5>
{children} {children}

View File

@ -32,14 +32,14 @@ export type GraphContextMenuProps = ContextMenuProps & {
}; };
/** @internal */ /** @internal */
export const GraphContextMenu: React.FC<GraphContextMenuProps> = ({ export const GraphContextMenu = ({
getContextMenuSource, getContextMenuSource,
timeZone, timeZone,
itemsGroup, itemsGroup,
dimensions, dimensions,
contextDimensions, contextDimensions,
...otherProps ...otherProps
}) => { }: GraphContextMenuProps) => {
const source = getContextMenuSource(); const source = getContextMenuSource();
// Do not render items that do not have label specified // Do not render items that do not have label specified

View File

@ -8,12 +8,12 @@ import { getMultiSeriesGraphHoverInfo } from '../utils';
import { GraphTooltipContentProps } from './types'; import { GraphTooltipContentProps } from './types';
export const MultiModeGraphTooltip: React.FC< type Props = GraphTooltipContentProps & {
GraphTooltipContentProps & { // We expect position to figure out correct values when not hovering over a datapoint
// We expect position to figure out correct values when not hovering over a datapoint pos: FlotPosition;
pos: FlotPosition; };
}
> = ({ dimensions, activeDimensions, pos, timeZone }) => { export const MultiModeGraphTooltip = ({ dimensions, activeDimensions, pos, timeZone }: Props) => {
let activeSeriesIndex: number | null = null; let activeSeriesIndex: number | null = null;
// when no x-axis provided, skip rendering // when no x-axis provided, skip rendering
if (activeDimensions.xAxis === null) { if (activeDimensions.xAxis === null) {

View File

@ -11,11 +11,7 @@ import { SeriesTable } from '../../VizTooltip';
import { GraphTooltipContentProps } from './types'; import { GraphTooltipContentProps } from './types';
export const SingleModeGraphTooltip: React.FC<GraphTooltipContentProps> = ({ export const SingleModeGraphTooltip = ({ dimensions, activeDimensions, timeZone }: GraphTooltipContentProps) => {
dimensions,
activeDimensions,
timeZone,
}) => {
// not hovering over a point, skip rendering // not hovering over a point, skip rendering
if ( if (
activeDimensions.yAxis === null || activeDimensions.yAxis === null ||

View File

@ -47,7 +47,7 @@ interface FeatureBadgeProps {
tooltip?: string; tooltip?: string;
} }
export const FeatureBadge: React.FC<FeatureBadgeProps> = ({ featureState, tooltip }) => { export const FeatureBadge = ({ featureState, tooltip }: FeatureBadgeProps) => {
const display = getPanelStateBadgeDisplayModel(featureState); const display = getPanelStateBadgeDisplayModel(featureState);
return <Badge text={display.text} color={display.color} icon={display.icon} tooltip={tooltip} />; return <Badge text={display.text} color={display.color} icon={display.icon} tooltip={tooltip} />;
}; };

View File

@ -25,7 +25,7 @@ export interface MenuGroupProps extends Partial<MenuItemsGroup> {
} }
/** @internal */ /** @internal */
export const MenuGroup: React.FC<MenuGroupProps> = ({ label, ariaLabel, children }) => { export const MenuGroup = ({ label, ariaLabel, children }: MenuGroupProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const labelID = `group-label-${uniqueId()}`; const labelID = `group-label-${uniqueId()}`;

View File

@ -28,8 +28,8 @@ export interface SubMenuProps {
} }
/** @internal */ /** @internal */
export const SubMenu: React.FC<SubMenuProps> = React.memo( export const SubMenu = React.memo(
({ items, isOpen, openedWithArrow, setOpenedWithArrow, close, customStyle }) => { ({ items, isOpen, openedWithArrow, setOpenedWithArrow, close, customStyle }: SubMenuProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const localRef = useRef<HTMLDivElement>(null); const localRef = useRef<HTMLDivElement>(null);
const [handleKeys] = useMenuFocus({ const [handleKeys] = useMenuFocus({

View File

@ -17,7 +17,7 @@ export type ErrorIndicatorProps = {
/** /**
* @internal * @internal
*/ */
export const ErrorIndicator: React.FC<ErrorIndicatorProps> = ({ error, onClick }) => { export const ErrorIndicator = ({ error, onClick }: ErrorIndicatorProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
if (!error) { if (!error) {

View File

@ -18,7 +18,7 @@ export type LoadingIndicatorProps = {
/** /**
* @internal * @internal
*/ */
export const LoadingIndicator: React.FC<LoadingIndicatorProps> = ({ onCancel, loading }) => { export const LoadingIndicator = ({ onCancel, loading }: LoadingIndicatorProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
if (!loading) { if (!loading) {

View File

@ -14,7 +14,7 @@ export interface PluginSignatureBadgeProps extends HTMLAttributes<HTMLDivElement
/** /**
* @public * @public
*/ */
export const PluginSignatureBadge: React.FC<PluginSignatureBadgeProps> = ({ status, ...otherProps }) => { export const PluginSignatureBadge = ({ status, ...otherProps }: PluginSignatureBadgeProps) => {
const display = getSignatureDisplayModel(status); const display = getSignatureDisplayModel(status);
return ( return (
<Badge <Badge

View File

@ -25,7 +25,7 @@ export const useExpandableLabel = (
} }
}; };
const Label: React.FC<LabelProps> = ({ Component, onClick, disabled }) => ( const Label = ({ Component, onClick, disabled }: LabelProps) => (
<button <button
type="button" type="button"
className={buttonStyles} className={buttonStyles}

View File

@ -6,7 +6,7 @@ interface DropdownIndicatorProps {
isOpen: boolean; isOpen: boolean;
} }
export const DropdownIndicator: React.FC<DropdownIndicatorProps> = ({ isOpen }) => { export const DropdownIndicator = ({ isOpen }: DropdownIndicatorProps) => {
const icon = isOpen ? 'search' : 'angle-down'; const icon = isOpen ? 'search' : 'angle-down';
const size = isOpen ? 'sm' : 'md'; const size = isOpen ? 'sm' : 'md';
return <Icon name={icon} size={size} />; return <Icon name={icon} size={size} />;

View File

@ -52,7 +52,7 @@ const getSeriesTableRowStyles = (theme: GrafanaTheme2) => {
/** /**
* @public * @public
*/ */
export const SeriesTableRow: React.FC<SeriesTableRowProps> = ({ color, label, value, isActive }) => { export const SeriesTableRow = ({ color, label, value, isActive }: SeriesTableRowProps) => {
const styles = useStyles2(getSeriesTableRowStyles); const styles = useStyles2(getSeriesTableRowStyles);
return ( return (
@ -79,7 +79,7 @@ export interface SeriesTableProps {
/** /**
* @public * @public
*/ */
export const SeriesTable: React.FC<SeriesTableProps> = ({ timestamp, series }) => { export const SeriesTable = ({ timestamp, series }: SeriesTableProps) => {
const styles = useStyles2(getSeriesTableRowStyles); const styles = useStyles2(getSeriesTableRowStyles);
return ( return (

View File

@ -22,14 +22,14 @@ export interface VizTooltipContainerProps extends HTMLAttributes<HTMLDivElement>
/** /**
* @public * @public
*/ */
export const VizTooltipContainer: React.FC<VizTooltipContainerProps> = ({ export const VizTooltipContainer = ({
position: { x: positionX, y: positionY }, position: { x: positionX, y: positionY },
offset: { x: offsetX, y: offsetY }, offset: { x: offsetX, y: offsetY },
children, children,
allowPointerEvents = false, allowPointerEvents = false,
className, className,
...otherProps ...otherProps
}) => { }: VizTooltipContainerProps) => {
const tooltipRef = useRef<HTMLDivElement>(null); const tooltipRef = useRef<HTMLDivElement>(null);
const [tooltipMeasurement, setTooltipMeasurement] = useState<Dimensions2D>({ width: 0, height: 0 }); const [tooltipMeasurement, setTooltipMeasurement] = useState<Dimensions2D>({ width: 0, height: 0 });
const { width, height } = useWindowSize(); const { width, height } = useWindowSize();

View File

@ -27,8 +27,8 @@ interface PlotLegendProps extends VizLegendOptions, Omit<VizLayoutLegendProps, '
config: UPlotConfigBuilder; config: UPlotConfigBuilder;
} }
export const PlotLegend: React.FC<PlotLegendProps> = React.memo( export const PlotLegend = React.memo(
({ data, config, placement, calcs, displayMode, ...vizLayoutLegendProps }) => { ({ data, config, placement, calcs, displayMode, ...vizLayoutLegendProps }: PlotLegendProps) => {
const theme = useTheme2(); const theme = useTheme2();
const legendItems = config const legendItems = config
.getSeries() .getSeries()

View File

@ -1,5 +1,5 @@
import { clamp } from 'lodash'; import { clamp } from 'lodash';
import React, { useLayoutEffect } from 'react'; import { useLayoutEffect } from 'react';
import uPlot from 'uplot'; import uPlot from 'uplot';
import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder'; import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder';
@ -170,7 +170,7 @@ const initHook = (u: uPlot) => {
/** /**
* @alpha * @alpha
*/ */
export const KeyboardPlugin: React.FC<KeyboardPluginProps> = ({ config }) => { export const KeyboardPlugin = ({ config }: KeyboardPluginProps) => {
useLayoutEffect(() => config.addHook('init', initHook), [config]); useLayoutEffect(() => config.addHook('init', initHook), [config]);
return null; return null;

View File

@ -40,7 +40,7 @@ const TOOLTIP_OFFSET = 10;
/** /**
* @alpha * @alpha
*/ */
export const TooltipPlugin: React.FC<TooltipPluginProps> = ({ export const TooltipPlugin = ({
mode = TooltipDisplayMode.Single, mode = TooltipDisplayMode.Single,
sortOrder = SortOrder.None, sortOrder = SortOrder.None,
sync, sync,
@ -48,7 +48,7 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({
config, config,
renderTooltip, renderTooltip,
...otherProps ...otherProps
}) => { }: TooltipPluginProps) => {
const plotInstance = useRef<uPlot>(); const plotInstance = useRef<uPlot>();
const theme = useTheme2(); const theme = useTheme2();
const [focusedSeriesIdx, setFocusedSeriesIdx] = useState<number | null>(null); const [focusedSeriesIdx, setFocusedSeriesIdx] = useState<number | null>(null);

View File

@ -1,4 +1,4 @@
import React, { useEffect, useLayoutEffect, useState } from 'react'; import { useEffect, useLayoutEffect, useState } from 'react';
import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder'; import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder';
import { PlotSelection } from '../types'; import { PlotSelection } from '../types';
@ -15,7 +15,7 @@ const MIN_ZOOM_DIST = 5;
/** /**
* @alpha * @alpha
*/ */
export const ZoomPlugin: React.FC<ZoomPluginProps> = ({ onZoom, config }) => { export const ZoomPlugin = ({ onZoom, config }: ZoomPluginProps) => {
const [selection, setSelection] = useState<PlotSelection | null>(null); const [selection, setSelection] = useState<PlotSelection | null>(null);
useEffect(() => { useEffect(() => {

View File

@ -6,9 +6,7 @@ import { HideableFieldConfig, HideSeriesConfig } from '@grafana/schema';
import { FilterPill, HorizontalGroup } from '../../index'; import { FilterPill, HorizontalGroup } from '../../index';
const SeriesConfigEditor: React.FC<FieldConfigEditorProps<HideSeriesConfig, {}>> = (props) => { const SeriesConfigEditor = ({ value, onChange }: FieldConfigEditorProps<HideSeriesConfig, {}>) => {
const { value, onChange } = props;
const onChangeToggle = useCallback( const onChangeToggle = useCallback(
(prop: keyof HideSeriesConfig) => { (prop: keyof HideSeriesConfig) => {
onChange({ ...value, [prop]: !value[prop] }); onChange({ ...value, [prop]: !value[prop] });

View File

@ -18,12 +18,7 @@ import {
Tooltip, Tooltip,
} from '../..'; } from '../..';
export const StackingEditor: React.FC<FieldOverrideEditorProps<StackingConfig, any>> = ({ export const StackingEditor = ({ value, context, onChange, item }: FieldOverrideEditorProps<StackingConfig, any>) => {
value,
context,
onChange,
item,
}) => {
return ( return (
<HorizontalGroup> <HorizontalGroup>
<RadioButtonGroup <RadioButtonGroup

View File

@ -34,7 +34,7 @@ describe('useStyles', () => {
}); });
it('passes in theme and returns style object', (done) => { it('passes in theme and returns style object', (done) => {
const Dummy: React.FC = function () { const Dummy = function () {
const styles = useStyles2((theme) => { const styles = useStyles2((theme) => {
return { return {
someStyle: css` someStyle: css`

View File

@ -8,9 +8,10 @@ import { GrafanaLight, GrafanaDark } from '../../../.storybook/storybookTheme';
type Props = { type Props = {
context: DocsContextProps; context: DocsContextProps;
children?: React.ReactNode;
}; };
export const ThemedDocsContainer: React.FC<Props> = ({ children, context }) => { export const ThemedDocsContainer = ({ children, context }: Props) => {
const dark = useDarkMode(); const dark = useDarkMode();
return ( return (

View File

@ -17,12 +17,9 @@ import { useStyles2, useTheme2, Field, RadioButtonGroup, Select } from '@grafana
import { ColorValueEditor } from './color'; import { ColorValueEditor } from './color';
export const FieldColorEditor: React.FC<FieldConfigEditorProps<FieldColor | undefined, FieldColorConfigSettings>> = ({ type Props = FieldConfigEditorProps<FieldColor | undefined, FieldColorConfigSettings>;
value,
onChange, export const FieldColorEditor = ({ value, onChange, item, id }: Props) => {
item,
id,
}) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);

View File

@ -8,11 +8,9 @@ import {
} from '@grafana/data'; } from '@grafana/data';
import { DataLinksInlineEditor } from '@grafana/ui'; import { DataLinksInlineEditor } from '@grafana/ui';
export const DataLinksValueEditor: React.FC<FieldConfigEditorProps<DataLink[], DataLinksFieldConfigSettings>> = ({ type Props = FieldConfigEditorProps<DataLink[], DataLinksFieldConfigSettings>;
value,
onChange, export const DataLinksValueEditor = ({ value, onChange, context }: Props) => {
context,
}) => {
return ( return (
<DataLinksInlineEditor <DataLinksInlineEditor
links={value} links={value}

View File

@ -4,11 +4,9 @@ import { FieldConfigEditorProps, NumberFieldConfigSettings } from '@grafana/data
import { NumberInput } from './NumberInput'; import { NumberInput } from './NumberInput';
export const NumberValueEditor: React.FC<FieldConfigEditorProps<number, NumberFieldConfigSettings>> = ({ type Props = FieldConfigEditorProps<number, NumberFieldConfigSettings>;
value,
onChange, export const NumberValueEditor = ({ value, onChange, item }: Props) => {
item,
}) => {
const { settings } = item; const { settings } = item;
const onValueChange = useCallback( const onValueChange = useCallback(

View File

@ -9,11 +9,9 @@ import { getStyles } from '@grafana/ui/src/components/Slider/styles';
import { NumberInput } from './NumberInput'; import { NumberInput } from './NumberInput';
export const SliderValueEditor: React.FC<FieldConfigEditorProps<number, SliderFieldConfigSettings>> = ({ type Props = FieldConfigEditorProps<number, SliderFieldConfigSettings>;
value,
onChange, export const SliderValueEditor = ({ value, onChange, item }: Props) => {
item,
}) => {
// Input reference // Input reference
const inputRef = useRef<HTMLSpanElement>(null); const inputRef = useRef<HTMLSpanElement>(null);

View File

@ -3,12 +3,12 @@ import React from 'react';
import { FieldConfigEditorProps, StatsPickerConfigSettings } from '@grafana/data'; import { FieldConfigEditorProps, StatsPickerConfigSettings } from '@grafana/data';
import { StatsPicker } from '@grafana/ui'; import { StatsPicker } from '@grafana/ui';
export const StatsPickerEditor: React.FC<FieldConfigEditorProps<string[], StatsPickerConfigSettings>> = ({ export const StatsPickerEditor = ({
value, value,
onChange, onChange,
item, item,
id, id,
}) => { }: FieldConfigEditorProps<string[], StatsPickerConfigSettings>) => {
return ( return (
<StatsPicker <StatsPicker
stats={value} stats={value}

View File

@ -13,13 +13,7 @@ export interface QueryOperationActionProps {
active?: boolean; active?: boolean;
} }
export const QueryOperationAction: React.FC<QueryOperationActionProps> = ({ export const QueryOperationAction = ({ icon, active, disabled, title, onClick }: QueryOperationActionProps) => {
icon,
active,
disabled,
title,
onClick,
}) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (

View File

@ -18,7 +18,7 @@ interface QueryOperationRowHeaderProps {
id: string; id: string;
} }
export const QueryOperationRowHeader: React.FC<QueryOperationRowHeaderProps> = ({ export const QueryOperationRowHeader = ({
actionsElement, actionsElement,
disabled, disabled,
draggable, draggable,

View File

@ -21,7 +21,7 @@ interface KBarResultsProps {
maxHeight?: number; maxHeight?: number;
} }
export const KBarResults: React.FC<KBarResultsProps> = (props) => { export const KBarResults = (props: KBarResultsProps) => {
const activeRef = React.useRef<HTMLElement>(null); const activeRef = React.useRef<HTMLElement>(null);
const parentRef = React.useRef(null); const parentRef = React.useRef(null);

View File

@ -16,7 +16,9 @@ const getStyles = (theme: GrafanaTheme2) => ({
`, `,
}); });
export const CategoryHeader: React.FC<{ iconName: IconName; label: string }> = ({ iconName, label }) => { type Props = { iconName: IconName; label: string };
export const CategoryHeader = ({ iconName, label }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (
<div className={styles.categoryHeader}> <div className={styles.categoryHeader}>

View File

@ -207,7 +207,7 @@ interface AddPanelWidgetHandleProps {
styles: AddPanelStyles; styles: AddPanelStyles;
} }
const AddPanelWidgetHandle: React.FC<AddPanelWidgetHandleProps> = ({ children, onBack, onCancel, styles }) => { const AddPanelWidgetHandle = ({ children, onBack, onCancel, styles }: AddPanelWidgetHandleProps) => {
return ( return (
<div className={cx(styles.headerRow, 'grid-drag-handle')}> <div className={cx(styles.headerRow, 'grid-drag-handle')}>
{onBack && ( {onBack && (

View File

@ -6,7 +6,7 @@ import { Button, useStyles2 } from '@grafana/ui';
export interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {} export interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {}
export const ListNewButton: React.FC<Props> = ({ children, ...restProps }) => { export const ListNewButton = ({ children, ...restProps }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (
<div className={styles.buttonWrapper}> <div className={styles.buttonWrapper}>

View File

@ -41,7 +41,7 @@ type LinkSettingsEditProps = {
onGoBack: () => void; onGoBack: () => void;
}; };
export const LinkSettingsEdit: React.FC<LinkSettingsEditProps> = ({ editLinkIdx, dashboard, onGoBack }) => { export const LinkSettingsEdit = ({ editLinkIdx, dashboard, onGoBack }: LinkSettingsEditProps) => {
const [linkSettings, setLinkSettings] = useState(editLinkIdx !== null ? dashboard.links[editLinkIdx] : newLink); const [linkSettings, setLinkSettings] = useState(editLinkIdx !== null ? dashboard.links[editLinkIdx] : newLink);
const onUpdate = (link: DashboardLink) => { const onUpdate = (link: DashboardLink) => {

View File

@ -13,7 +13,7 @@ type LinkSettingsListProps = {
onEdit: (idx: number) => void; onEdit: (idx: number) => void;
}; };
export const LinkSettingsList: React.FC<LinkSettingsListProps> = ({ dashboard, onNew, onEdit }) => { export const LinkSettingsList = ({ dashboard, onNew, onEdit }: LinkSettingsListProps) => {
const [links, setLinks] = useState(dashboard.links); const [links, setLinks] = useState(dashboard.links);
const moveLink = (idx: number, direction: number) => { const moveLink = (idx: number, direction: number) => {

View File

@ -23,7 +23,7 @@ interface DynamicConfigValueEditorProps {
searchQuery: string; searchQuery: string;
} }
export const DynamicConfigValueEditor: React.FC<DynamicConfigValueEditorProps> = ({ export const DynamicConfigValueEditor = ({
property, property,
context, context,
registry, registry,
@ -31,7 +31,7 @@ export const DynamicConfigValueEditor: React.FC<DynamicConfigValueEditorProps> =
onRemove, onRemove,
isSystemOverride, isSystemOverride,
searchQuery, searchQuery,
}) => { }: DynamicConfigValueEditorProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const item = registry?.getIfExists(property.id); const item = registry?.getIfExists(property.id);

View File

@ -12,7 +12,7 @@ import { VisualizationSelectPane } from './VisualizationSelectPane';
import { OptionPaneRenderProps } from './types'; import { OptionPaneRenderProps } from './types';
import { usePanelLatestData } from './usePanelLatestData'; import { usePanelLatestData } from './usePanelLatestData';
export const OptionsPane: React.FC<OptionPaneRenderProps> = ({ export const OptionsPane = ({
plugin, plugin,
panel, panel,
onFieldConfigsChange, onFieldConfigsChange,
@ -20,7 +20,7 @@ export const OptionsPane: React.FC<OptionPaneRenderProps> = ({
onPanelConfigChange, onPanelConfigChange,
dashboard, dashboard,
instanceState, instanceState,
}) => { }: OptionPaneRenderProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const isVizPickerOpen = useSelector((state) => state.panelEditor.isVizPickerOpen); const isVizPickerOpen = useSelector((state) => state.panelEditor.isVizPickerOpen);
const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, true); const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, true);

View File

@ -17,7 +17,7 @@ import { OptionSearchEngine } from './state/OptionSearchEngine';
import { getRecentOptions } from './state/getRecentOptions'; import { getRecentOptions } from './state/getRecentOptions';
import { OptionPaneRenderProps } from './types'; import { OptionPaneRenderProps } from './types';
export const OptionsPaneOptions: React.FC<OptionPaneRenderProps> = (props) => { export const OptionsPaneOptions = (props: OptionPaneRenderProps) => {
const { plugin, dashboard, panel } = props; const { plugin, dashboard, panel } = props;
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const [listMode, setListMode] = useState(OptionFilter.All); const [listMode, setListMode] = useState(OptionFilter.All);

View File

@ -13,7 +13,7 @@ interface SaveDashboardButtonProps {
size?: ComponentSize; size?: ComponentSize;
} }
export const SaveDashboardButton: React.FC<SaveDashboardButtonProps> = ({ dashboard, onSaveSuccess, size }) => { export const SaveDashboardButton = ({ dashboard, onSaveSuccess, size }: SaveDashboardButtonProps) => {
return ( return (
<ModalsController> <ModalsController>
{({ showModal, hideModal }) => { {({ showModal, hideModal }) => {
@ -37,12 +37,9 @@ export const SaveDashboardButton: React.FC<SaveDashboardButtonProps> = ({ dashbo
); );
}; };
export const SaveDashboardAsButton: React.FC<SaveDashboardButtonProps & { variant?: ButtonVariant }> = ({ type Props = SaveDashboardButtonProps & { variant?: ButtonVariant };
dashboard,
onSaveSuccess, export const SaveDashboardAsButton = ({ dashboard, onSaveSuccess, variant, size }: Props) => {
variant,
size,
}) => {
return ( return (
<ModalsController> <ModalsController>
{({ showModal, hideModal }) => { {({ showModal, hideModal }) => {

View File

@ -19,12 +19,12 @@ interface SaveDashboardErrorProxyProps {
onDismiss: () => void; onDismiss: () => void;
} }
export const SaveDashboardErrorProxy: React.FC<SaveDashboardErrorProxyProps> = ({ export const SaveDashboardErrorProxy = ({
dashboard, dashboard,
dashboardSaveModel, dashboardSaveModel,
error, error,
onDismiss, onDismiss,
}) => { }: SaveDashboardErrorProxyProps) => {
const { onDashboardSave } = useDashboardSave(dashboard); const { onDashboardSave } = useDashboardSave(dashboard);
useEffect(() => { useEffect(() => {

View File

@ -14,12 +14,7 @@ interface UnsavedChangesModalProps {
onSaveSuccess?: () => void; onSaveSuccess?: () => void;
} }
export const UnsavedChangesModal: React.FC<UnsavedChangesModalProps> = ({ export const UnsavedChangesModal = ({ dashboard, onSaveSuccess, onDiscard, onDismiss }: UnsavedChangesModalProps) => {
dashboard,
onSaveSuccess,
onDiscard,
onDismiss,
}) => {
return ( return (
<Modal <Modal
isOpen={true} isOpen={true}

View File

@ -38,13 +38,7 @@ export interface SaveDashboardAsFormProps extends SaveDashboardFormProps {
isNew?: boolean; isNew?: boolean;
} }
export const SaveDashboardAsForm: React.FC<SaveDashboardAsFormProps> = ({ export const SaveDashboardAsForm = ({ dashboard, isNew, onSubmit, onCancel, onSuccess }: SaveDashboardAsFormProps) => {
dashboard,
isNew,
onSubmit,
onCancel,
onSuccess,
}) => {
const defaultValues: SaveDashboardAsFormDTO = { const defaultValues: SaveDashboardAsFormDTO = {
title: isNew ? dashboard.title : `${dashboard.title} Copy`, title: isNew ? dashboard.title : `${dashboard.title} Copy`,
$folder: { $folder: {

View File

@ -7,7 +7,7 @@ import { Button, ClipboardButton, HorizontalGroup, TextArea } from '@grafana/ui'
import { SaveDashboardFormProps } from '../types'; import { SaveDashboardFormProps } from '../types';
export const SaveProvisionedDashboardForm: React.FC<SaveDashboardFormProps> = ({ dashboard, onCancel }) => { export const SaveProvisionedDashboardForm = ({ dashboard, onCancel }: SaveDashboardFormProps) => {
const [dashboardJSON, setDashboardJson] = useState(() => { const [dashboardJSON, setDashboardJson] = useState(() => {
const clone = dashboard.getSaveModelClone(); const clone = dashboard.getSaveModelClone();
delete clone.id; delete clone.id;

View File

@ -109,7 +109,7 @@ interface LinkElementProps {
children: JSX.Element; children: JSX.Element;
} }
const LinkElement: React.FC<LinkElementProps> = (props) => { const LinkElement = (props: LinkElementProps) => {
const { link, children, ...rest } = props; const { link, children, ...rest } = props;
return ( return (

View File

@ -12,12 +12,12 @@ interface TransformationOperationRowsProps {
onChange: (index: number, config: DataTransformerConfig) => void; onChange: (index: number, config: DataTransformerConfig) => void;
} }
export const TransformationOperationRows: React.FC<TransformationOperationRowsProps> = ({ export const TransformationOperationRows = ({
data, data,
onChange, onChange,
onRemove, onRemove,
configs, configs,
}) => { }: TransformationOperationRowsProps) => {
return ( return (
<> <>
{configs.map((t, i) => { {configs.map((t, i) => {

View File

@ -14,7 +14,7 @@ type DiffTitleProps = {
const replaceDiff: Diff = { op: 'replace', originalValue: undefined, path: [''], value: undefined, startLineNumber: 0 }; const replaceDiff: Diff = { op: 'replace', originalValue: undefined, path: [''], value: undefined, startLineNumber: 0 };
export const DiffTitle: React.FC<DiffTitleProps> = ({ diff, title }) => { export const DiffTitle = ({ diff, title }: DiffTitleProps) => {
const styles = useStyles2(getDiffTitleStyles); const styles = useStyles2(getDiffTitleStyles);
return diff ? ( return diff ? (

View File

@ -11,7 +11,7 @@ type DiffProps = {
diff: Diff; diff: Diff;
}; };
export const DiffValues: React.FC<DiffProps> = ({ diff }) => { export const DiffValues = ({ diff }: DiffProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const hasLeftValue = const hasLeftValue =
!isUndefined(diff.originalValue) && !isArray(diff.originalValue) && !isObject(diff.originalValue); !isUndefined(diff.originalValue) && !isArray(diff.originalValue) && !isObject(diff.originalValue);

View File

@ -5,7 +5,7 @@ import tinycolor from 'tinycolor2';
import { useTheme2 } from '@grafana/ui'; import { useTheme2 } from '@grafana/ui';
export const DiffViewer: React.FC<ReactDiffViewerProps> = ({ oldValue, newValue }) => { export const DiffViewer = ({ oldValue, newValue }: ReactDiffViewerProps) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = { const styles = {

View File

@ -8,7 +8,7 @@ export interface RevertDashboardModalProps {
version: number; version: number;
} }
export const RevertDashboardModal: React.FC<RevertDashboardModalProps> = ({ hideModal, version }) => { export const RevertDashboardModal = ({ hideModal, version }: RevertDashboardModalProps) => {
// TODO: how should state.error be handled? // TODO: how should state.error be handled?
const { state, onRestoreDashboard } = useDashboardRestore(version); const { state, onRestoreDashboard } = useDashboardRestore(version);

View File

@ -10,13 +10,13 @@ type VersionsButtonsType = {
getDiff: () => void; getDiff: () => void;
isLastPage: boolean; isLastPage: boolean;
}; };
export const VersionsHistoryButtons: React.FC<VersionsButtonsType> = ({ export const VersionsHistoryButtons = ({
hasMore, hasMore,
canCompare, canCompare,
getVersions, getVersions,
getDiff, getDiff,
isLastPage, isLastPage,
}) => ( }: VersionsButtonsType) => (
<Stack> <Stack>
{hasMore && ( {hasMore && (
<Button type="button" onClick={() => getVersions(true)} variant="secondary" disabled={isLastPage}> <Button type="button" onClick={() => getVersions(true)} variant="secondary" disabled={isLastPage}>

View File

@ -18,7 +18,7 @@ type DiffViewProps = {
diffData: { lhs: unknown; rhs: unknown }; diffData: { lhs: unknown; rhs: unknown };
}; };
export const VersionHistoryComparison: React.FC<DiffViewProps> = ({ baseInfo, newInfo, diffData, isNewLatest }) => { export const VersionHistoryComparison = ({ baseInfo, newInfo, diffData, isNewLatest }: DiffViewProps) => {
const diff = jsonDiff(diffData.lhs, diffData.rhs); const diff = jsonDiff(diffData.lhs, diffData.rhs);
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);

View File

@ -12,12 +12,12 @@ type VersionHistoryHeaderProps = {
isNewLatest?: boolean; isNewLatest?: boolean;
}; };
export const VersionHistoryHeader: React.FC<VersionHistoryHeaderProps> = ({ export const VersionHistoryHeader = ({
onClick = noop, onClick = noop,
baseVersion = 0, baseVersion = 0,
newVersion = 0, newVersion = 0,
isNewLatest = false, isNewLatest = false,
}) => { }: VersionHistoryHeaderProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (

View File

@ -10,7 +10,7 @@ import { createDashboardModelFixture } from '../state/__fixtures__/dashboardFixt
import { DashboardGrid, Props } from './DashboardGrid'; import { DashboardGrid, Props } from './DashboardGrid';
jest.mock('app/features/dashboard/dashgrid/LazyLoader', () => { jest.mock('app/features/dashboard/dashgrid/LazyLoader', () => {
const LazyLoader: React.FC = ({ children }) => { const LazyLoader = ({ children }: React.PropsWithChildren<{}>) => {
return <>{children}</>; return <>{children}</>;
}; };
return { LazyLoader }; return { LazyLoader };

View File

@ -183,7 +183,7 @@ export function References(props: ReferenceItemProps) {
); );
} }
const AccordianReferences: React.FC<AccordianReferencesProps> = ({ const AccordianReferences = ({
data, data,
interactive = true, interactive = true,
isOpen, isOpen,
@ -191,7 +191,7 @@ const AccordianReferences: React.FC<AccordianReferencesProps> = ({
onItemToggle, onItemToggle,
openedItems, openedItems,
createFocusSpanLink, createFocusSpanLink,
}) => { }: AccordianReferencesProps) => {
const isEmpty = !Array.isArray(data) || !data.length; const isEmpty = !Array.isArray(data) || !data.length;
let arrow: React.ReactNode | null = null; let arrow: React.ReactNode | null = null;
let HeaderComponent: 'span' | 'a' = 'span'; let HeaderComponent: 'span' | 'a' = 'span';

View File

@ -17,12 +17,9 @@ export interface LibraryPanelCardProps {
showSecondaryActions?: boolean; showSecondaryActions?: boolean;
} }
export const LibraryPanelCard: React.FC<LibraryPanelCardProps & { children?: JSX.Element | JSX.Element[] }> = ({ type Props = LibraryPanelCardProps & { children?: JSX.Element | JSX.Element[] };
libraryPanel,
onClick, export const LibraryPanelCard = ({ libraryPanel, onClick, onDelete, showSecondaryActions }: Props) => {
onDelete,
showSecondaryActions,
}) => {
const [showDeletionModal, setShowDeletionModal] = useState(false); const [showDeletionModal, setShowDeletionModal] = useState(false);
const onDeletePanel = () => { const onDeletePanel = () => {

View File

@ -23,7 +23,7 @@ interface LibraryPanelViewProps {
perPage?: number; perPage?: number;
} }
export const LibraryPanelsView: React.FC<LibraryPanelViewProps> = ({ export const LibraryPanelsView = ({
className, className,
onClickCard, onClickCard,
searchString, searchString,
@ -33,7 +33,7 @@ export const LibraryPanelsView: React.FC<LibraryPanelViewProps> = ({
showSecondaryActions, showSecondaryActions,
currentPanelId: currentPanel, currentPanelId: currentPanel,
perPage: propsPerPage = 40, perPage: propsPerPage = 40,
}) => { }: LibraryPanelViewProps) => {
const styles = useStyles2(getPanelViewStyles); const styles = useStyles2(getPanelViewStyles);
const [{ libraryPanels, page, perPage, numberOfPages, loadingState, currentPanelId }, dispatch] = useReducer( const [{ libraryPanels, page, perPage, numberOfPages, loadingState, currentPanelId }, dispatch] = useReducer(
libraryPanelsViewReducer, libraryPanelsViewReducer,

View File

@ -14,14 +14,7 @@ interface DatasetSelectorProps extends ResourceSelectorProps {
onChange: (v: SelectableValue) => void; onChange: (v: SelectableValue) => void;
} }
export const DatasetSelector: React.FC<DatasetSelectorProps> = ({ export const DatasetSelector = ({ db, value, onChange, disabled, className, applyDefault }: DatasetSelectorProps) => {
db,
value,
onChange,
disabled,
className,
applyDefault,
}) => {
const state = useAsync(async () => { const state = useAsync(async () => {
const datasets = await db.datasets(); const datasets = await db.datasets();
return datasets.map(toOption); return datasets.map(toOption);

View File

@ -15,7 +15,7 @@ interface TableSelectorProps extends ResourceSelectorProps {
forceFetch?: boolean; forceFetch?: boolean;
} }
export const TableSelector: React.FC<TableSelectorProps> = ({ db, query, value, className, onChange, forceFetch }) => { export const TableSelector = ({ db, query, value, className, onChange, forceFetch }: TableSelectorProps) => {
const state = useAsync(async () => { const state = useAsync(async () => {
if (!query.dataset && !forceFetch) { if (!query.dataset && !forceFetch) {
return []; return [];

View File

@ -18,14 +18,7 @@ interface VisualEditorProps extends QueryEditorProps {
onValidate: (isValid: boolean) => void; onValidate: (isValid: boolean) => void;
} }
export const VisualEditor: React.FC<VisualEditorProps> = ({ export const VisualEditor = ({ query, db, queryRowFilter, onChange, onValidate, range }: VisualEditorProps) => {
query,
db,
queryRowFilter,
onChange,
onValidate,
range,
}) => {
const state = useAsync(async () => { const state = useAsync(async () => {
const fields = await db.fields(query); const fields = await db.fields(query);
return fields; return fields;

View File

@ -34,9 +34,7 @@ const filterMatch: Array<SelectableValue<FilterByValueMatch>> = [
{ label: 'Match any', value: FilterByValueMatch.any }, { label: 'Match any', value: FilterByValueMatch.any },
]; ];
export const FilterByValueTransformerEditor: React.FC<TransformerUIProps<FilterByValueTransformerOptions>> = ( export const FilterByValueTransformerEditor = (props: TransformerUIProps<FilterByValueTransformerOptions>) => {
props
) => {
const { input, options, onChange } = props; const { input, options, onChange } = props;
const styles = getEditorStyles(); const styles = getEditorStyles();
const fieldsInfo = useFieldsInfo(input); const fieldsInfo = useFieldsInfo(input);

View File

@ -1,10 +1,8 @@
import React from 'react';
import { ValueMatcherID } from '@grafana/data'; import { ValueMatcherID } from '@grafana/data';
import { ValueMatcherUIProps, ValueMatcherUIRegistryItem } from './types'; import { ValueMatcherUIRegistryItem } from './types';
export const NoopMatcherEditor: React.FC<ValueMatcherUIProps<any>> = () => { export const NoopMatcherEditor = () => {
return null; return null;
}; };

View File

@ -23,7 +23,7 @@ const supplier = (
addHeatmapCalculationOptions('', builder, options); addHeatmapCalculationOptions('', builder, options);
}; };
export const HeatmapTransformerEditor: React.FC<TransformerUIProps<HeatmapTransformerOptions>> = (props) => { export const HeatmapTransformerEditor = (props: TransformerUIProps<HeatmapTransformerOptions>) => {
useEffect(() => { useEffect(() => {
if (!props.options.xBuckets?.mode) { if (!props.options.xBuckets?.mode) {
const opts = getDefaultOptions(supplier); const opts = getDefaultOptions(supplier);

View File

@ -25,11 +25,7 @@ const logModeOptions: Array<SelectableValue<HeatmapCalculationMode>> = [
}, },
]; ];
export const AxisEditor: React.FC<StandardEditorProps<HeatmapCalculationBucketConfig, any>> = ({ export const AxisEditor = ({ value, onChange, item }: StandardEditorProps<HeatmapCalculationBucketConfig>) => {
value,
onChange,
item,
}) => {
return ( return (
<HorizontalGroup> <HorizontalGroup>
<RadioButtonGroup <RadioButtonGroup

View File

@ -24,11 +24,11 @@ interface FieldProps {
onConfigChange: (config: GroupByFieldOptions) => void; onConfigChange: (config: GroupByFieldOptions) => void;
} }
export const GroupByTransformerEditor: React.FC<TransformerUIProps<GroupByTransformerOptions>> = ({ export const GroupByTransformerEditor = ({
input, input,
options, options,
onChange, onChange,
}) => { }: TransformerUIProps<GroupByTransformerOptions>) => {
const fieldNames = useAllFieldNamesFromDataFrames(input); const fieldNames = useAllFieldNamesFromDataFrames(input);
const onConfigChange = useCallback( const onConfigChange = useCallback(
@ -65,7 +65,7 @@ const options = [
{ label: 'Calculate', value: GroupByOperationID.aggregate }, { label: 'Calculate', value: GroupByOperationID.aggregate },
]; ];
export const GroupByFieldConfiguration: React.FC<FieldProps> = ({ fieldName, config, onConfigChange }) => { export const GroupByFieldConfiguration = ({ fieldName, config, onConfigChange }: FieldProps) => {
const styles = getStyling(); const styles = getStyling();
const onChange = useCallback( const onChange = useCallback(

View File

@ -13,11 +13,11 @@ import { InlineField, InlineFieldRow, Select } from '@grafana/ui';
import { useAllFieldNamesFromDataFrames } from '../utils'; import { useAllFieldNamesFromDataFrames } from '../utils';
export const GroupingToMatrixTransformerEditor: React.FC<TransformerUIProps<GroupingToMatrixTransformerOptions>> = ({ export const GroupingToMatrixTransformerEditor = ({
input, input,
options, options,
onChange, onChange,
}) => { }: TransformerUIProps<GroupingToMatrixTransformerOptions>) => {
const fieldNames = useAllFieldNamesFromDataFrames(input).map((item: string) => ({ label: item, value: item })); const fieldNames = useAllFieldNamesFromDataFrames(input).map((item: string) => ({ label: item, value: item }));
const onSelectColumn = useCallback( const onSelectColumn = useCallback(

View File

@ -8,11 +8,11 @@ import {
import { InlineField, InlineFieldRow, InlineSwitch } from '@grafana/ui'; import { InlineField, InlineFieldRow, InlineSwitch } from '@grafana/ui';
import { NumberInput } from 'app/core/components/OptionsUI/NumberInput'; import { NumberInput } from 'app/core/components/OptionsUI/NumberInput';
export const HistogramTransformerEditor: React.FC<TransformerUIProps<HistogramTransformerOptions>> = ({ export const HistogramTransformerEditor = ({
input, input,
options, options,
onChange, onChange,
}) => { }: TransformerUIProps<HistogramTransformerOptions>) => {
const labelWidth = 18; const labelWidth = 18;
const onBucketSizeChanged = useCallback( const onBucketSizeChanged = useCallback(

View File

@ -19,11 +19,11 @@ const modes: Array<SelectableValue<LabelsToFieldsMode>> = [
{ value: LabelsToFieldsMode.Rows, label: 'Rows' }, { value: LabelsToFieldsMode.Rows, label: 'Rows' },
]; ];
export const LabelsAsFieldsTransformerEditor: React.FC<TransformerUIProps<LabelsToFieldsOptions>> = ({ export const LabelsAsFieldsTransformerEditor = ({
input, input,
options, options,
onChange, onChange,
}) => { }: TransformerUIProps<LabelsToFieldsOptions>) => {
const labelWidth = 20; const labelWidth = 20;
const { labelNames, selected } = useMemo(() => { const { labelNames, selected } = useMemo(() => {

View File

@ -4,10 +4,7 @@ import { DataTransformerID, standardTransformers, TransformerRegistryItem, Trans
import { LimitTransformerOptions } from '@grafana/data/src/transformations/transformers/limit'; import { LimitTransformerOptions } from '@grafana/data/src/transformations/transformers/limit';
import { InlineField, InlineFieldRow, Input } from '@grafana/ui'; import { InlineField, InlineFieldRow, Input } from '@grafana/ui';
export const LimitTransformerEditor: React.FC<TransformerUIProps<LimitTransformerOptions>> = ({ export const LimitTransformerEditor = ({ options, onChange }: TransformerUIProps<LimitTransformerOptions>) => {
options,
onChange,
}) => {
const onSetLimit = useCallback( const onSetLimit = useCallback(
(value: FormEvent<HTMLInputElement>) => { (value: FormEvent<HTMLInputElement>) => {
onChange({ onChange({

View File

@ -4,11 +4,7 @@ import { DataTransformerID, standardTransformers, TransformerRegistryItem, Trans
import { MergeTransformerOptions } from '@grafana/data/src/transformations/transformers/merge'; import { MergeTransformerOptions } from '@grafana/data/src/transformations/transformers/merge';
import { FieldValidationMessage } from '@grafana/ui'; import { FieldValidationMessage } from '@grafana/ui';
export const MergeTransformerEditor: React.FC<TransformerUIProps<MergeTransformerOptions>> = ({ export const MergeTransformerEditor = ({ input, options, onChange }: TransformerUIProps<MergeTransformerOptions>) => {
input,
options,
onChange,
}) => {
if (input.length <= 1) { if (input.length <= 1) {
// Show warning that merge is useless only apply on a single frame // Show warning that merge is useless only apply on a single frame
return <FieldValidationMessage>Merge has no effect when applied on a single frame.</FieldValidationMessage>; return <FieldValidationMessage>Merge has no effect when applied on a single frame.</FieldValidationMessage>;

View File

@ -13,10 +13,7 @@ import { selectors } from '@grafana/e2e-selectors';
import { LegacyForms, Select, StatsPicker } from '@grafana/ui'; import { LegacyForms, Select, StatsPicker } from '@grafana/ui';
// TODO: Minimal implementation, needs some <3 // TODO: Minimal implementation, needs some <3
export const ReduceTransformerEditor: React.FC<TransformerUIProps<ReduceTransformerOptions>> = ({ export const ReduceTransformerEditor = ({ options, onChange }: TransformerUIProps<ReduceTransformerOptions>) => {
options,
onChange,
}) => {
const modes: Array<SelectableValue<ReduceTransformerMode>> = [ const modes: Array<SelectableValue<ReduceTransformerMode>> = [
{ {
label: 'Series to rows', label: 'Series to rows',

View File

@ -1,13 +1,11 @@
import React from 'react';
import { DataTransformerID, standardTransformers, TransformerRegistryItem, TransformerUIProps } from '@grafana/data'; import { DataTransformerID, standardTransformers, TransformerRegistryItem, TransformerUIProps } from '@grafana/data';
import { SeriesToRowsTransformerOptions } from '@grafana/data/src/transformations/transformers/seriesToRows'; import { SeriesToRowsTransformerOptions } from '@grafana/data/src/transformations/transformers/seriesToRows';
export const SeriesToRowsTransformerEditor: React.FC<TransformerUIProps<SeriesToRowsTransformerOptions>> = ({ export const SeriesToRowsTransformerEditor = ({
input, input,
options, options,
onChange, onChange,
}) => { }: TransformerUIProps<SeriesToRowsTransformerOptions>) => {
return null; return null;
}; };

View File

@ -6,11 +6,7 @@ import { InlineField, InlineSwitch, InlineFieldRow, Select } from '@grafana/ui';
import { useAllFieldNamesFromDataFrames } from '../utils'; import { useAllFieldNamesFromDataFrames } from '../utils';
export const SortByTransformerEditor: React.FC<TransformerUIProps<SortByTransformerOptions>> = ({ export const SortByTransformerEditor = ({ input, options, onChange }: TransformerUIProps<SortByTransformerOptions>) => {
input,
options,
onChange,
}) => {
const fieldNames = useAllFieldNamesFromDataFrames(input).map((item: string) => ({ label: item, value: item })); const fieldNames = useAllFieldNamesFromDataFrames(input).map((item: string) => ({ label: item, value: item }));
// Only supports single sort for now // Only supports single sort for now

View File

@ -26,11 +26,11 @@ const fieldNamePickerSettings: StandardEditorsRegistryItem<string, FieldNamePick
editor: () => null, editor: () => null,
}; };
export const extractFieldsTransformerEditor: React.FC<TransformerUIProps<ExtractFieldsOptions>> = ({ export const extractFieldsTransformerEditor = ({
input, input,
options, options,
onChange, onChange,
}) => { }: TransformerUIProps<ExtractFieldsOptions>) => {
const onPickSourceField = (source?: string) => { const onPickSourceField = (source?: string) => {
onChange({ onChange({
...options, ...options,

View File

@ -31,11 +31,7 @@ const fieldLookupSettings: StandardEditorsRegistryItem<string, GazetteerPathEdit
settings: {}, settings: {},
} as any; } as any;
export const FieldLookupTransformerEditor: React.FC<TransformerUIProps<FieldLookupOptions>> = ({ export const FieldLookupTransformerEditor = ({ input, options, onChange }: TransformerUIProps<FieldLookupOptions>) => {
input,
options,
onChange,
}) => {
const onPickLookupField = useCallback( const onPickLookupField = useCallback(
(value: string | undefined) => { (value: string | undefined) => {
onChange({ onChange({

View File

@ -113,7 +113,9 @@ const supplier = (
} }
}; };
export const SetGeometryTransformerEditor: React.FC<TransformerUIProps<SpatialTransformOptions>> = (props) => { type Props = TransformerUIProps<SpatialTransformOptions>;
export const SetGeometryTransformerEditor = (props: Props) => {
// a new component is created with every change :( // a new component is created with every change :(
useEffect(() => { useEffect(() => {
if (!props.options.source?.mode) { if (!props.options.source?.mode) {

View File

@ -44,14 +44,14 @@ function selectSubscriptions(
return querySubscriptions; return querySubscriptions;
} }
const ArgQueryEditor: React.FC<ArgQueryEditorProps> = ({ const ArgQueryEditor = ({
query, query,
datasource, datasource,
subscriptionId, subscriptionId,
variableOptionGroup, variableOptionGroup,
onChange, onChange,
setError, setError,
}) => { }: ArgQueryEditorProps) => {
const [subscriptions, setSubscriptions] = useState<AzureMonitorOption[]>([]); const [subscriptions, setSubscriptions] = useState<AzureMonitorOption[]>([]);
useMemo(() => { useMemo(() => {
datasource datasource

View File

@ -4,7 +4,7 @@ import { CodeEditor } from '@grafana/ui';
import { AzureQueryEditorFieldProps } from '../../types'; import { AzureQueryEditorFieldProps } from '../../types';
const QueryField: React.FC<AzureQueryEditorFieldProps> = ({ query, onQueryChange }) => { const QueryField = ({ query, onQueryChange }: AzureQueryEditorFieldProps) => {
const onChange = useCallback( const onChange = useCallback(
(newQuery: string) => { (newQuery: string) => {
onQueryChange({ onQueryChange({

Some files were not shown because too many files have changed in this diff Show More