Having a text field grow with its contents is a much nicer experience than having to scroll all the way through it. Writing and reviewing articles for my website wasn’t the easiest because of that. I mostly wrote in a text editor and copied/pasted to avoid having to scroll as much. That work-flow put some barriers up in terms of getting an article written. I’ve been experimenting with Stimulus lately, and figured it would be a good learning experience to solve the problem using it.
It really isn’t all that complex. There are different, and likely better, ways to solve this problem.
// expandable_field_controller.js
import { Controller } from 'stimulus'
export default class extends Controller {
static targets = ['input']
initialize() {
this.setup()
this.resize()
}
setup() {
this.inputTarget.style.height = `${this.inputTarget.scrollHeight}px`
}
resize() {
this.inputTarget.style.height = 'auto'
this.inputTarget.style.height = `${this.inputTarget.scrollHeight}px`
}
}
It’s worth noting that I have a min-height
set on <textarea>
controls that this is used with. Setting the height to auto
on the resize()
call prevented a weird bug when reducing the height (?). I chose to use the input
event to trigger the behaviour.
<div data-controller="expandable-field">
<%=
form.text_area :content,
data: {
target: "expandable-field.input",
action: "input->expandable-field#resize"
}
%>
</div>