Files
GS13NG/tgui-next/packages/tgui/components/Input.js
T
2020-01-20 13:42:10 +02:00

139 lines
3.0 KiB
JavaScript

import { classes, isFalsy } from 'common/react';
import { Component, createRef } from 'inferno';
import { Box } from './Box';
const toInputValue = value => {
if (isFalsy(value)) {
return '';
}
return value;
};
export class Input extends Component {
constructor() {
super();
this.inputRef = createRef();
this.state = {
editing: false,
};
this.handleInput = e => {
const { editing } = this.state;
const { onInput } = this.props;
if (!editing) {
this.setEditing(true);
}
if (onInput) {
onInput(e, e.target.value);
}
};
this.handleFocus = e => {
const { editing } = this.state;
if (!editing) {
this.setEditing(true);
}
};
this.handleBlur = e => {
const { editing } = this.state;
const { onChange } = this.props;
if (editing) {
this.setEditing(false);
if (onChange) {
onChange(e, e.target.value);
}
}
};
this.handleKeyDown = e => {
const { onInput, onChange, onEnter } = this.props;
if (e.keyCode === 13) {
this.setEditing(false);
if (onChange) {
onChange(e, e.target.value);
}
if (onInput) {
onInput(e, e.target.value);
}
if (onEnter) {
onEnter(e, e.target.value);
}
if (this.props.selfClear) {
e.target.value = '';
} else {
e.target.blur();
}
return;
}
if (e.keyCode === 27) {
this.setEditing(false);
e.target.value = toInputValue(this.props.value);
e.target.blur();
return;
}
};
}
componentDidMount() {
const nextValue = this.props.value;
const input = this.inputRef.current;
if (input) {
input.value = toInputValue(nextValue);
}
}
componentDidUpdate(prevProps, prevState) {
const { editing } = this.state;
const prevValue = prevProps.value;
const nextValue = this.props.value;
const input = this.inputRef.current;
if (input && !editing && prevValue !== nextValue) {
input.value = toInputValue(nextValue);
}
}
setEditing(editing) {
this.setState({ editing });
}
render() {
const { props } = this;
// Input only props
const {
selfClear,
onInput,
onChange,
onEnter,
value,
maxLength,
placeholder,
...boxProps
} = props;
// Box props
const {
className,
fluid,
...rest
} = boxProps;
return (
<Box
className={classes([
'Input',
fluid && 'Input--fluid',
className,
])}
{...rest}>
<div className="Input__baseline">
.
</div>
<input
ref={this.inputRef}
className="Input__input"
placeholder={placeholder}
onInput={this.handleInput}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
onKeyDown={this.handleKeyDown}
maxLength={maxLength} />
</Box>
);
}
}