UNPKG

@zag-js/auto-resize

Version:

Autoresize utilities for the web

59 lines (58 loc) 2.13 kB
// src/autoresize-textarea.ts import { getComputedStyle, getDocument, getWindow } from "@zag-js/dom-query"; var autoresizeTextarea = (el) => { if (!el) return; const style = getComputedStyle(el); const win = getWindow(el); const doc = getDocument(el); const resize = () => { requestAnimationFrame(() => { el.style.height = "auto"; let newHeight; if (style.boxSizing === "content-box") { newHeight = el.scrollHeight - (parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); } else { newHeight = el.scrollHeight + parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); } if (style.maxHeight !== "none" && newHeight > parseFloat(style.maxHeight)) { if (style.overflowY === "hidden") { el.style.overflowY = "scroll"; } newHeight = parseFloat(style.maxHeight); } else if (style.overflowY !== "hidden") { el.style.overflowY = "hidden"; } el.style.height = `${newHeight}px`; }); }; el.addEventListener("input", resize); el.form?.addEventListener("reset", resize); const ownDescriptor = Object.getOwnPropertyDescriptor(el, "value"); const descriptor = ownDescriptor?.set ? ownDescriptor : Object.getOwnPropertyDescriptor(Object.getPrototypeOf(el), "value"); if (descriptor?.set) { Object.defineProperty(el, "value", { ...descriptor, set(newValue) { descriptor.set?.call(this, newValue); resize(); } }); } const resizeObserver = new win.ResizeObserver(() => { requestAnimationFrame(() => resize()); }); resizeObserver.observe(el); const attrObserver = new win.MutationObserver(() => resize()); attrObserver.observe(el, { attributes: true, attributeFilter: ["rows", "placeholder"] }); doc.fonts?.addEventListener("loadingdone", resize); return () => { el.removeEventListener("input", resize); el.form?.removeEventListener("reset", resize); doc.fonts?.removeEventListener("loadingdone", resize); resizeObserver.disconnect(); attrObserver.disconnect(); }; }; export { autoresizeTextarea };