Skip to content

Commit eac725d

Browse files
author
Martin Krulis
committed
Improvement of comment text area resizing.
1 parent bc307ae commit eac725d

File tree

1 file changed

+46
-8
lines changed

1 file changed

+46
-8
lines changed

src/components/widgets/Comments/AddComment/AddComment.js

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Form, FormGroup, FormControl, InputGroup, HelpBlock } from 'react-boots
55

66
import Button from '../../FlatButton';
77
import Icon from '../../../icons';
8+
import { safeGet } from '../../../../helpers/common';
89

910
const messages = defineMessages({
1011
placeholder: {
@@ -13,18 +14,54 @@ const messages = defineMessages({
1314
},
1415
});
1516

17+
const textareaStyle = { resize: 'none', overflow: 'hidden', height: 'auto' };
18+
19+
const updateTextareaHeight = textarea => {
20+
const saveScrollPos = window.scrollY; // we need to save viewport scroll position first
21+
22+
// First we make it small (reset the size)
23+
textarea.style.height = '1px';
24+
const newHeight = 2 + textarea.scrollHeight; // and see, how large the scroll area really is
25+
const maxHeight = 500;
26+
27+
if (newHeight > maxHeight) {
28+
// Set the height to maximum and allow scrollbars inside textarea
29+
textarea.style.height = `${maxHeight}px`;
30+
textarea.style.overflow = 'auto';
31+
} else {
32+
// Set the height to match actual text size and disable scrollbars
33+
textarea.style.height = `${newHeight}px`;
34+
textarea.style.overflow = 'hidden';
35+
textarea.scrollTop = 0;
36+
}
37+
38+
window.scrollTo(window.scrollX, saveScrollPos); // restore viewport scroll position (prevent document jumping)
39+
};
40+
1641
class AddComment extends Component {
1742
state = { text: '', isPrivate: false };
1843

19-
changeText = text => this.setState({ text });
44+
handleTextareaChange = ev => {
45+
const textarea = ev.target;
46+
this.setState({ text: textarea.value });
47+
updateTextareaHeight(textarea);
48+
};
49+
2050
togglePrivate = () => this.setState({ isPrivate: !this.state.isPrivate });
2151

22-
addComment = e => {
23-
e.preventDefault();
52+
addComment = ev => {
2453
const { text, isPrivate } = this.state;
2554
const { addComment } = this.props;
2655
addComment(text, isPrivate);
2756
this.setState({ text: '' });
57+
58+
ev.preventDefault();
59+
const formElement = safeGet(ev, ['currentTarget', 'form']);
60+
const textarea = formElement && formElement.querySelector('textarea');
61+
if (textarea) {
62+
textarea.value = '';
63+
updateTextareaHeight(textarea);
64+
}
2865
};
2966

3067
render() {
@@ -41,10 +78,11 @@ class AddComment extends Component {
4178
<InputGroup>
4279
<FormControl
4380
componentClass="textarea"
44-
rows={text.split('\n').length}
45-
style={{ resize: 'none', overflow: 'hidden' }}
81+
rows={1}
82+
style={textareaStyle}
4683
disabled={!addComment}
47-
onChange={e => this.changeText(e.target.value)}
84+
onChange={this.handleTextareaChange}
85+
onInput={this.handleTextareInput}
4886
placeholder={formatMessage(messages.placeholder)}
4987
value={text}
5088
/>
@@ -62,13 +100,13 @@ class AddComment extends Component {
62100
</InputGroup.Button>
63101
</InputGroup>
64102
<HelpBlock>
65-
<Button onClick={this.togglePrivate} bsSize="xs" disabled={!addComment}>
103+
<Button onClick={this.togglePrivate} bsSize="xs" disabled={!addComment} className="halfem-margin-right">
66104
{isPrivate ? (
67105
<Icon icon="lock" className="text-success" />
68106
) : (
69107
<Icon icon="unlock-alt" className="text-warning" />
70108
)}
71-
</Button>{' '}
109+
</Button>
72110
{isPrivate && (
73111
<FormattedHTMLMessage
74112
id="app.comments.warnings.isPrivate"

0 commit comments

Comments
 (0)