Reputation: 63
So far I have done this:
<textarea rows='2' onChange={e => setSomething(e.target.value)}
className='form-control text-area ' value={something} placeholder='write something'>
</textarea>
output:
Expected Requirement:
I need to change the value of row property dynamically according to the text line. If the number of text line increases, then row property value will also increase. But if it is more than 8, then we have to use scroll-bar.
Upvotes: 1
Views: 4916
Reputation: 21181
I guess what you actually want is to dynamically resize the textarea to match the content:
height
of the textarea to auto
and then to the value of textarea.scrollHeight
.minHeight
to that value:maxHeight
, and making sure minHeight
is not set to a value greater than that. Beyond that, scrollbars will appear:function resizeTextArea(textarea) {
const { style, value } = textarea;
// The 4 corresponds to the 2 2px borders (top and bottom):
style.height = style.minHeight = 'auto';
style.minHeight = `${ Math.min(textarea.scrollHeight + 4, parseInt(textarea.style.maxHeight)) }px`;
style.height = `${ textarea.scrollHeight + 4 }px`;
}
const textarea = document.getElementById('textarea');
textarea.addEventListener('input', () => {
resizeTextArea(textarea);
});
#textarea {
display: block;
margin: 0;
padding: 8px;
border: 2px solid black;
width: 100%;
box-sizing: border-box;
resize: vertical;
}
<textarea id="textarea" style="max-height: 140px; "></textarea>
An improved version of would not shrink down the textarea if the user has manually expanded it, unless they shrink it back to fit the content. It would, however, still expand automatically if the content becomes larger than the user-defined height:
function resizeTextArea(textarea, userDefinedHeight = 0) {
const { style, value } = textarea;
// The 4 corresponds to the 2 2px borders (top and bottom):
style.height = style.minHeight = 'auto';
style.minHeight = `${ Math.min(textarea.scrollHeight + 4, parseInt(textarea.style.maxHeight)) }px`;
style.height = `${ Math.max(textarea.scrollHeight + 4, userDefinedHeight) }px`;
}
const textarea = document.getElementById('textarea');
let userDefinedHeight = 0;
textarea.addEventListener('input', () => {
resizeTextArea(textarea, userDefinedHeight);
});
textarea.addEventListener('mouseup', () => {
const { height, minHeight } = textarea.style;
// Do not shrink beyond user-defined values (if they expand it manually),
// but go back to auto-resizing if they shrink it back to the content size:
userDefinedHeight = height === minHeight ? 0 : parseInt(height, 10);
});
#textarea {
display: block;
margin: 0;
padding: 8px;
border: 2px solid black;
width: 100%;
box-sizing: border-box;
resize: vertical;
}
<textarea id="textarea" style="max-height: 140px; "></textarea>
Upvotes: 3
Reputation: 25406
You can do this if you set row property dynamically according to the number of newlines are there as:
Live Demo
import { useState } from "react";
import "./styles.css";
export default function App() {
const [rows, setRows] = useState(2);
const [value, setValue] = useState("");
function setTextAreaInput(e) {
const val = e.target.value;
setValue(val);
const newLines = val.match(/\n/g)?.length;
if (!newLines) setRows(2);
else if (newLines < 8) setRows(newLines + 1);
else setRows(8);
}
return (
<div>
<textarea
rows={rows}
onChange={(e) => setTextAreaInput(e)}
className="form-control text-area "
value={value}
placeholder="write something"></textarea>
</div>
);
}
Upvotes: 1