Skip to content

Instantly share code, notes, and snippets.

@sjmog
Last active April 7, 2021 01:01
Show Gist options
  • Save sjmog/f825e11f9714dddc87c71f3127c984a0 to your computer and use it in GitHub Desktop.
Save sjmog/f825e11f9714dddc87c71f3127c984a0 to your computer and use it in GitHub Desktop.
// An implementation of https://css-tricks.com/the-cleanest-trick-for-autogrowing-textareas/ in React
import React, { useRef } from 'react'
const AutoGrowingTextArea = props => {
const grower = useRef(null);
return(
<div className="AutoGrowingTextArea" ref={grower}>
<textarea
name={props.name}
id={props.id}
onInput={ (e) => grower.current.dataset.replicatedValue = e.target.value }></textarea>
</div>
)
}
AutoGrowingTextArea.defaultProps = {
name: 'text',
id: 'text'
}
export default AutoGrowingTextArea
.AutoGrowingTextArea {
/* easy way to plop the elements on top of each other and have them both sized based on the tallest one's height */
display: grid;
}
.AutoGrowingTextArea::after {
/* Note the weird space! Needed to preventy jumpy behavior */
content: attr(data-replicated-value) " ";
/* This is how textarea text behaves */
white-space: pre-wrap;
/* Hidden from view, clicks, and screen readers */
visibility: hidden;
}
.AutoGrowingTextArea > textarea {
/* You could leave this, but after a user resizes, then it ruins the auto sizing */
resize: none;
/* Firefox shows scrollbar on growth, you can hide like this. */
overflow: hidden;
}
.AutoGrowingTextArea > textarea,
.AutoGrowingTextArea::after {
/* Identical styling required!! */
border: 1px solid black;
padding: 0.5rem;
font: inherit;
/* Place on top of each other */
grid-area: 1 / 1 / 2 / 2;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment