Skip to content

Instantly share code, notes, and snippets.

@sungchuni
Last active December 7, 2020 15:11
Show Gist options
  • Save sungchuni/39c6307445fca79d56f475da720509b0 to your computer and use it in GitHub Desktop.
Save sungchuni/39c6307445fca79d56f475da720509b0 to your computer and use it in GitHub Desktop.
export default {
bind,
update,
};
const debouncedAutoRowsHandler = debounce(autoRowsHandler);
function bind(el, binding) {
if (!(el instanceof HTMLTextAreaElement)) {
throw new TypeError("element should be instance of HTMLTextAreaElement");
}
const handler = debouncedAutoRowsHandler.bind({el, binding});
el.onblur = handler;
el.onfocus = handler;
el.oninput = handler;
}
function update(el, binding) {
debouncedAutoRowsHandler.call({el, binding});
}
function autoRowsHandler({type} = {}) {
const {
el,
binding: {value},
} = this;
const scrollingElement =
document.scrollingElement || document.documentElement;
const {scrollTop: beforeScrollTop} = scrollingElement;
const {clientHeight: beforeClientHeight} = el;
el.style.height =
(typeof value === "number" && `${value}px`) || value || null;
if (el.scrollHeight > el.clientHeight) {
el.style.height = `${el.scrollHeight}px`;
}
scrollingElement.scrollTop = beforeScrollTop;
if (type === "input") {
const margin = 72;
const viewportHeight =
"VisualViewport" in window
? visualViewport.height
: scrollingElement.clientHeight;
const {bottom} = el.parentElement.getBoundingClientRect();
const afterOverflow = bottom - viewportHeight;
const beforeOverflow =
afterOverflow - (el.clientHeight - beforeClientHeight);
if (beforeOverflow < 0 && afterOverflow > -margin) {
scrollingElement.scrollTop += afterOverflow + margin;
}
}
}
function debounce(fn, wait) {
let cancelId = null
const hasWait = Number.isSafeInteger(wait)
const [timer, cancel] =
hasWait
? [setTimeout, clearTimeout]
: [requestAnimationFrame, cancelAnimationFrame]
return function debounced(...args) {
cancel(cancelId)
cancelId = timer(fn.bind(this, ...args), wait)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment