summaryrefslogtreecommitdiffstats
path: root/webapp/components/autosize_textarea.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/components/autosize_textarea.jsx')
-rw-r--r--webapp/components/autosize_textarea.jsx90
1 files changed, 90 insertions, 0 deletions
diff --git a/webapp/components/autosize_textarea.jsx b/webapp/components/autosize_textarea.jsx
new file mode 100644
index 000000000..45807fda0
--- /dev/null
+++ b/webapp/components/autosize_textarea.jsx
@@ -0,0 +1,90 @@
+// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import React from 'react';
+
+export default class AutosizeTextarea extends React.Component {
+ static propTypes = {
+ value: React.PropTypes.string,
+ placeholder: React.PropTypes.string,
+ onHeightChange: React.PropTypes.func
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.height = 0;
+ }
+
+ get value() {
+ return this.refs.textarea.value;
+ }
+
+ set value(value) {
+ this.refs.textarea.value = value;
+ }
+
+ componentDidUpdate() {
+ this.recalculateSize();
+ }
+
+ recalculateSize() {
+ const height = this.refs.reference.scrollHeight;
+
+ if (height > 0 && height !== this.height) {
+ const textarea = this.refs.textarea;
+
+ const style = getComputedStyle(textarea);
+ const borderWidth = parseInt(style.borderTopWidth, 10) + parseInt(style.borderBottomWidth, 10);
+
+ // Directly change the height to avoid circular rerenders
+ textarea.style.height = String(height + borderWidth) + 'px';
+
+ this.height = height;
+
+ if (this.props.onHeightChange) {
+ this.props.onHeightChange(height, parseInt(style.maxHeight, 10));
+ }
+ }
+ }
+
+ getDOMNode() {
+ return this.refs.textarea;
+ }
+
+ render() {
+ window.forceUpdate = this.forceUpdate.bind(this);
+ const {
+ value,
+ placeholder,
+ ...otherProps
+ } = this.props;
+
+ const heightProps = {};
+ if (this.height <= 0) {
+ // Set an initial number of rows so that the textarea doesn't appear too large when its first rendered
+ heightProps.rows = 1;
+ } else {
+ heightProps.height = this.height;
+ }
+
+ return (
+ <div>
+ <textarea
+ ref='textarea'
+ {...heightProps}
+ {...this.props}
+ />
+ <div style={{height: 0, overflow: 'hidden'}}>
+ <textarea
+ ref='reference'
+ style={{height: 'auto', width: '100%'}}
+ value={value || placeholder}
+ rows='1'
+ {...otherProps}
+ />
+ </div>
+ </div>
+ );
+ }
+} \ No newline at end of file