You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
40 lines
1.1 KiB
JavaScript
40 lines
1.1 KiB
JavaScript
"use strict";
|
|
|
|
const React = require("react");
|
|
const classnames = require("classnames");
|
|
|
|
const style = require("./autoresize-textarea.css");
|
|
|
|
const NBSP = String.fromCharCode(160);
|
|
|
|
module.exports = React.forwardRef(function AutosizeTextarea({ value, className, onChange, ... args }, ref) {
|
|
// TODO: Handle this outside of the React state cycle using raw JS events, for improved performance
|
|
let [ currentValue, setCurrentValue ] = React.useState(value);
|
|
|
|
// This is mainly to ensure that an empty newline is taken into account for the size measurement, otherwise we get a scrollbar in the textarea
|
|
let displayValue = currentValue + (currentValue.endsWith("\n") ? NBSP : "");
|
|
|
|
return (
|
|
<div className={classnames(style.wrapper)}>
|
|
<div className={classnames(style.dummy, className)}>{displayValue}</div>
|
|
<textarea
|
|
ref={ref}
|
|
rows="1" cols="1"
|
|
name="value"
|
|
className={classnames(style.editable, className)}
|
|
value={currentValue}
|
|
onChange={(event) => {
|
|
let newValue = event.target.value;
|
|
|
|
setCurrentValue(newValue);
|
|
|
|
if (onChange != null) {
|
|
onChange(newValue);
|
|
}
|
|
}}
|
|
{... args}
|
|
/>
|
|
</div>
|
|
);
|
|
});
|