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> ); } } |