-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
68 lines (57 loc) · 1.83 KB
/
index.js
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
customElements.define(
"elastic-textarea",
class extends HTMLElement {
connectedCallback() {
[...this.querySelectorAll("textarea")].forEach((textareaEl) => {
textareaEl.setAttribute(
"data-min-rows",
textareaEl.getAttribute("rows") || 2
);
this.update(textareaEl);
});
// TODO: Do I also need change?
this.addEventListener("input", ({ target }) => {
if (!target instanceof HTMLTextAreaElement) return;
this.update(textareaEl);
});
}
isScrolling(textareaEl) {
textareaEl.scrollHeight > textareaEl.clientHeight;
}
/** Grow until the textarea stops scrolling */
grow(textareaEl) {
// Store initial height of textarea
let previousHeight = textareaEl.clientHeight;
while (isScrolling(textareaEl)) {
rows++;
textareaEl.setAttribute("rows", String(rows));
// Get height after rows change is made
const newHeight = textareaEl.clientHeight;
// If the height hasn't changed, break the loop
// This safety check is to prevent an infinite loop in IE11
if (newHeight === previousHeight) break;
// Store the updated height for the next comparison and proceed
previousHeight = newHeight;
}
}
/** Shrink until the textarea matches the minimum rows or starts scrolling */
shrink() {
const minRows = textareaEl.getAttribute("data-min-rows");
while (!isScrolling(textareaEl) && rows > minRows) {
rows--;
textareaEl.setAttribute("rows", String(Math.max(rows, minRows)));
if (isScrolling(textareaEl)) {
grow(textareaEl);
break;
}
}
}
update() {
if (isScrolling(textareaEl)) {
grow(textareaEl);
} else {
shrink(textareaEl);
}
}
}
);