Commit 07fc2486 by Dominik Prokop Committed by GitHub

Field/panel options - do not trigger change events onChange, but onBlur or enter key press (#24388)

* Field options - do not trigger change events onChange, but onBlur or enter key press

* Review changes

* fix ts
parent bb436e74
import React from 'react';
import React, { useCallback } from 'react';
import {
FieldConfigEditorProps,
toIntegerOrUndefined,
......@@ -13,19 +13,42 @@ export const NumberValueEditor: React.FC<FieldConfigEditorProps<number, NumberFi
item,
}) => {
const { settings } = item;
const onValueChange = useCallback(
(e: React.SyntheticEvent) => {
if (e.hasOwnProperty('key')) {
// handling keyboard event
const evt = e as React.KeyboardEvent<HTMLInputElement>;
if (evt.key === 'Enter') {
onChange(
settings?.integer
? toIntegerOrUndefined(evt.currentTarget.value)
: toFloatOrUndefined(evt.currentTarget.value)
);
}
} else {
// handling form event
const evt = e as React.FormEvent<HTMLInputElement>;
onChange(
settings?.integer
? toIntegerOrUndefined(evt.currentTarget.value)
: toFloatOrUndefined(evt.currentTarget.value)
);
}
},
[onChange]
);
return (
<Input
value={isNaN(value) ? '' : value}
defaultValue={isNaN(value) ? '' : value.toString()}
min={settings?.min}
max={settings?.max}
type="number"
step={settings?.step}
placeholder={settings?.placeholder}
onChange={e => {
onChange(
settings?.integer ? toIntegerOrUndefined(e.currentTarget.value) : toFloatOrUndefined(e.currentTarget.value)
);
}}
onBlur={onValueChange}
onKeyDown={onValueChange}
/>
);
};
import React from 'react';
import React, { useCallback } from 'react';
import { FieldConfigEditorProps, StringFieldConfigSettings } from '@grafana/data';
import { Input } from '../Input/Input';
import { TextArea } from '../TextArea/TextArea';
......@@ -9,14 +9,31 @@ export const StringValueEditor: React.FC<FieldConfigEditorProps<string, StringFi
item,
}) => {
const Component = item.settings?.useTextarea ? TextArea : Input;
const onValueChange = useCallback(
(e: React.SyntheticEvent) => {
if (e.hasOwnProperty('key')) {
// handling keyboard event
const evt = e as React.KeyboardEvent<HTMLInputElement>;
if (evt.key === 'Enter' && !item.settings?.useTextarea) {
onChange(evt.currentTarget.value.trim() === '' ? undefined : evt.currentTarget.value);
}
} else {
// handling form event
const evt = e as React.FormEvent<HTMLInputElement>;
onChange(evt.currentTarget.value.trim() === '' ? undefined : evt.currentTarget.value);
}
},
[onChange]
);
return (
<Component
placeholder={item.settings?.placeholder}
value={value || ''}
defaultValue={value || ''}
rows={item.settings?.useTextarea && item.settings.rows}
onChange={(e: React.FormEvent<any>) =>
onChange(e.currentTarget.value.trim() === '' ? undefined : e.currentTarget.value)
}
onBlur={onValueChange}
onKeyDown={onValueChange}
/>
);
};
import React, { ChangeEvent } from 'react';
import React from 'react';
import { HorizontalGroup } from '../Layout/Layout';
import { IconButton, Label, RadioButtonGroup } from '../index';
import { Field } from '../Forms/Field';
......@@ -19,41 +19,61 @@ const MAPPING_OPTIONS: Array<SelectableValue<MappingType>> = [
export const MappingRow: React.FC<Props> = ({ valueMapping, updateValueMapping, removeValueMapping }) => {
const { type } = valueMapping;
const onMappingValueChange = (event: ChangeEvent<HTMLInputElement>) => {
updateValueMapping({ ...valueMapping, value: event.target.value });
const onMappingValueChange = (value: string) => {
updateValueMapping({ ...valueMapping, value: value });
};
const onMappingFromChange = (event: ChangeEvent<HTMLInputElement>) => {
updateValueMapping({ ...valueMapping, from: event.target.value });
const onMappingFromChange = (value: string) => {
updateValueMapping({ ...valueMapping, from: value });
};
const onMappingToChange = (event: ChangeEvent<HTMLInputElement>) => {
updateValueMapping({ ...valueMapping, to: event.target.value });
const onMappingToChange = (value: string) => {
updateValueMapping({ ...valueMapping, to: value });
};
const onMappingTextChange = (event: ChangeEvent<HTMLInputElement>) => {
updateValueMapping({ ...valueMapping, text: event.target.value });
const onMappingTextChange = (value: string) => {
updateValueMapping({ ...valueMapping, text: value });
};
const onMappingTypeChange = (mappingType: MappingType) => {
updateValueMapping({ ...valueMapping, type: mappingType });
};
const onKeyDown = (handler: (value: string) => void) => (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handler(e.currentTarget.value);
}
};
const renderRow = () => {
if (type === MappingType.RangeToText) {
return (
<>
<HorizontalGroup>
<Field label="From">
<Input type="number" defaultValue={(valueMapping as RangeMap).from!} onBlur={onMappingFromChange} />
<Input
type="number"
defaultValue={(valueMapping as RangeMap).from!}
onBlur={e => onMappingFromChange(e.currentTarget.value)}
onKeyDown={onKeyDown(onMappingFromChange)}
/>
</Field>
<Field label="To">
<Input type="number" defaultValue={(valueMapping as RangeMap).to} onBlur={onMappingToChange} />
<Input
type="number"
defaultValue={(valueMapping as RangeMap).to}
onBlur={e => onMappingToChange(e.currentTarget.value)}
onKeyDown={onKeyDown(onMappingToChange)}
/>
</Field>
</HorizontalGroup>
<Field label="Text">
<Input defaultValue={valueMapping.text} onBlur={onMappingTextChange} />
<Input
defaultValue={valueMapping.text}
onBlur={e => onMappingTextChange(e.currentTarget.value)}
onKeyDown={onKeyDown(onMappingTextChange)}
/>
</Field>
</>
);
......@@ -62,11 +82,20 @@ export const MappingRow: React.FC<Props> = ({ valueMapping, updateValueMapping,
return (
<>
<Field label="Value">
<Input type="number" defaultValue={(valueMapping as ValueMap).value} onBlur={onMappingValueChange} />
<Input
type="number"
defaultValue={(valueMapping as ValueMap).value}
onBlur={e => onMappingValueChange(e.currentTarget.value)}
onKeyDown={onKeyDown(onMappingValueChange)}
/>
</Field>
<Field label="Text">
<Input defaultValue={valueMapping.text} onBlur={onMappingTextChange} />
<Input
defaultValue={valueMapping.text}
onBlur={e => onMappingTextChange(e.currentTarget.value)}
onKeyDown={onKeyDown(onMappingTextChange)}
/>
</Field>
</>
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment