Files
Erik Sundell 0e4850f203 UI: Segment fixes (#20947)
* 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
2019-12-10 13:00:22 +01:00

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);
}
}}
/>
);
}