Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 1x 1x 1x | import React, { ChangeEvent, Component, createRef, RefObject } from "react";
import { getInputClass, WidgetProps } from "./types";
const style = {
display: "block",
overflow: "hidden",
resize: "none",
} as const;
export class MultiLineTextInputWidget extends Component<WidgetProps> {
textarea: RefObject<HTMLTextAreaElement>;
constructor(props: WidgetProps) {
super(props);
this.textarea = createRef();
this.onChange = this.onChange.bind(this);
this.recalculateSize = this.recalculateSize.bind(this);
}
onChange(event: ChangeEvent<HTMLTextAreaElement>) {
this.recalculateSize();
this.props.onChange(event.target.value);
}
componentDidMount() {
this.recalculateSize();
window.addEventListener("resize", this.recalculateSize);
}
componentWillUnmount() {
window.removeEventListener("resize", this.recalculateSize);
}
componentDidUpdate() {
this.recalculateSize();
}
recalculateSize() {
const node = this.textarea.current;
if (!node) {
return;
}
const style = window.getComputedStyle(node);
const diff =
style.getPropertyValue("box-sizing") === "border-box"
? 0
: parseInt(style.getPropertyValue("padding-bottom") || "0", 10) +
parseInt(style.getPropertyValue("padding-top") || "0", 10);
const updateScrollPosition = node === document.activeElement;
// Cross-browser compatibility for scroll position
const oldScrollTop =
document.documentElement.scrollTop || document.body.scrollTop;
const oldHeight = node.offsetHeight;
node.style.height = "auto";
const newHeight = node.scrollHeight - diff;
node.style.height = newHeight + "px";
if (updateScrollPosition) {
window.scrollTo(
document.body.scrollLeft,
oldScrollTop + (newHeight - oldHeight)
);
}
}
render() {
const { type, value, placeholder, disabled } = this.props;
return (
<div>
<textarea
ref={this.textarea}
className={getInputClass(type)}
onChange={this.onChange}
style={style}
value={value}
disabled={disabled}
placeholder={placeholder}
/>
</div>
);
}
}
|