1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-11-04 10:02:40 +01:00

New TEXT_AREA input type

This commit is contained in:
ta264 2020-09-07 21:05:07 +01:00
parent f8c3947bad
commit e014826b17
4 changed files with 197 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import QualityProfileSelectInputConnector from './QualityProfileSelectInputConne
import RootFolderSelectInputConnector from './RootFolderSelectInputConnector';
import TagInputConnector from './TagInputConnector';
import TagSelectInputConnector from './TagSelectInputConnector';
import TextArea from './TextArea';
import TextInput from './TextInput';
import TextTagInputConnector from './TextTagInputConnector';
import styles from './FormInputGroup.css';
@ -71,6 +72,9 @@ function getComponent(type) {
case inputTypes.TAG:
return TagInputConnector;
case inputTypes.TEXT_AREA:
return TextArea;
case inputTypes.TEXT_TAG:
return TextTagInputConnector;

View File

@ -0,0 +1,19 @@
.input {
composes: input from '~Components/Form/Input.css';
flex-grow: 1;
min-height: 200px;
resize: vertical;
}
.readOnly {
background-color: #eee;
}
.hasError {
composes: hasError from '~Components/Form/Input.css';
}
.hasWarning {
composes: hasWarning from '~Components/Form/Input.css';
}

View File

@ -0,0 +1,172 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import styles from './TextArea.css';
class TextArea extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this._input = null;
this._selectionStart = null;
this._selectionEnd = null;
this._selectionTimeout = null;
this._isMouseTarget = false;
}
componentDidMount() {
window.addEventListener('mouseup', this.onDocumentMouseUp);
}
componentWillUnmount() {
window.removeEventListener('mouseup', this.onDocumentMouseUp);
if (this._selectionTimeout) {
this._selectionTimeout = clearTimeout(this._selectionTimeout);
}
}
//
// Control
setInputRef = (ref) => {
this._input = ref;
}
selectionChange() {
if (this._selectionTimeout) {
this._selectionTimeout = clearTimeout(this._selectionTimeout);
}
this._selectionTimeout = setTimeout(() => {
const selectionStart = this._input.selectionStart;
const selectionEnd = this._input.selectionEnd;
const selectionChanged = (
this._selectionStart !== selectionStart ||
this._selectionEnd !== selectionEnd
);
this._selectionStart = selectionStart;
this._selectionEnd = selectionEnd;
if (this.props.onSelectionChange && selectionChanged) {
this.props.onSelectionChange(selectionStart, selectionEnd);
}
}, 10);
}
//
// Listeners
onChange = (event) => {
const {
name,
onChange
} = this.props;
const payload = {
name,
value: event.target.value
};
onChange(payload);
}
onFocus = (event) => {
if (this.props.onFocus) {
this.props.onFocus(event);
}
this.selectionChange();
}
onKeyUp = () => {
this.selectionChange();
}
onMouseDown = () => {
this._isMouseTarget = true;
}
onMouseUp = () => {
this.selectionChange();
}
onDocumentMouseUp = () => {
if (this._isMouseTarget) {
this.selectionChange();
}
this._isMouseTarget = false;
}
//
// Render
render() {
const {
className,
readOnly,
autoFocus,
placeholder,
name,
value,
hasError,
hasWarning,
onBlur
} = this.props;
return (
<textarea
ref={this.setInputRef}
readOnly={readOnly}
autoFocus={autoFocus}
placeholder={placeholder}
className={classNames(
className,
readOnly && styles.readOnly,
hasError && styles.hasError,
hasWarning && styles.hasWarning
)}
name={name}
value={value}
onChange={this.onChange}
onFocus={this.onFocus}
onBlur={onBlur}
onKeyUp={this.onKeyUp}
onMouseDown={this.onMouseDown}
onMouseUp={this.onMouseUp}
/>
);
}
}
TextArea.propTypes = {
className: PropTypes.string.isRequired,
readOnly: PropTypes.bool,
autoFocus: PropTypes.bool,
placeholder: PropTypes.string,
name: PropTypes.string.isRequired,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]).isRequired,
hasError: PropTypes.bool,
hasWarning: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
onSelectionChange: PropTypes.func
};
TextArea.defaultProps = {
className: styles.input,
type: 'text',
readOnly: false,
autoFocus: false,
value: ''
};
export default TextArea;

View File

@ -13,6 +13,7 @@ export const ROOT_FOLDER_SELECT = 'rootFolderSelect';
export const SELECT = 'select';
export const TAG = 'tag';
export const TEXT = 'text';
export const TEXT_AREA = 'textArea';
export const TEXT_TAG = 'textTag';
export const TAG_SELECT = 'tagSelect';
@ -32,6 +33,7 @@ export const all = [
SELECT,
TAG,
TEXT,
TEXT_AREA,
TEXT_TAG,
TAG_SELECT
];