mirror of
https://github.com/grafana/grafana.git
synced 2025-09-25 21:04:05 +08:00

* Add support for primitive values/onchange * Fix segment clickaway bug * Fix onchange * Use primitive in cloudwatch * Add placeholder * Use placeholder in cloudwatch editor * Fix lint error * Fix lodash import * Use new component story format * Add support for autofocus * Use selectable value for onchange event * Fix lint error
75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
import React, { useRef, useState } from 'react';
|
|
import { cx, css } from 'emotion';
|
|
import useClickAway from 'react-use/lib/useClickAway';
|
|
import { measureText } from '../../utils/measureText';
|
|
import { useExpandableLabel, SegmentProps } from '.';
|
|
|
|
export interface SegmentInputProps<T> extends SegmentProps<T> {
|
|
value: string | number;
|
|
onChange: (text: string | number) => void;
|
|
autofocus?: boolean;
|
|
}
|
|
|
|
const FONT_SIZE = 14;
|
|
|
|
export function SegmentInput<T>({
|
|
value: initialValue,
|
|
onChange,
|
|
Component,
|
|
className,
|
|
placeholder,
|
|
autofocus = false,
|
|
}: React.PropsWithChildren<SegmentInputProps<T>>) {
|
|
const ref = useRef<HTMLInputElement>(null);
|
|
const [value, setValue] = useState<number | string>(initialValue);
|
|
const [inputWidth, setInputWidth] = useState<number>(measureText((initialValue || '').toString(), FONT_SIZE).width);
|
|
const [Label, , expanded, setExpanded] = useExpandableLabel(autofocus);
|
|
|
|
useClickAway(ref, () => {
|
|
setExpanded(false);
|
|
onChange(value);
|
|
});
|
|
|
|
if (!expanded) {
|
|
return (
|
|
<Label
|
|
Component={
|
|
Component || (
|
|
<a className={cx('gf-form-label', 'query-part', !value && placeholder && 'query-placeholder', className)}>
|
|
{initialValue || placeholder}
|
|
</a>
|
|
)
|
|
}
|
|
/>
|
|
);
|
|
}
|
|
|
|
const inputWidthStyle = css`
|
|
width: ${Math.max(inputWidth + 20, 32)}px;
|
|
`;
|
|
|
|
return (
|
|
<input
|
|
ref={ref}
|
|
autoFocus
|
|
className={cx(`gf-form gf-form-input`, inputWidthStyle)}
|
|
value={value}
|
|
onChange={item => {
|
|
const { width } = measureText(item.target.value, FONT_SIZE);
|
|
setInputWidth(width);
|
|
setValue(item.target.value);
|
|
}}
|
|
onBlur={() => {
|
|
setExpanded(false);
|
|
onChange(value);
|
|
}}
|
|
onKeyDown={e => {
|
|
if ([13, 27].includes(e.keyCode)) {
|
|
setExpanded(false);
|
|
onChange(value);
|
|
}
|
|
}}
|
|
/>
|
|
);
|
|
}
|