Vue directive - autosize

by joplomacedo

HTML

<div id="app">
  <b-input v-autosize />
</div>

CSS

input {
  font-size: 15px;
  line-height: 1.5;
  font-weight: 900;
  padding: 1em;
}

Vue

function getStyle(el, prop) {
	return el.currentStyle
		? el.currentStyle[prop]
		: window.getComputedStyle(el, null)[prop];
}

function setWidth(el, mimicEl) {
    if ( el.lastRecordedValue === el.value ) return;

	mimicEl.innerText = el.value;
    el.style.width = mimicEl.offsetWidth + 10 + "px";
    el.lastRecordedValue = el.value;
}

function normalizeOptions( options ) {
    let defaults = {
        minWidth: "none",
        maxWidth: "none"
    };
        
    let normalizedOptions = { ...options };

    if ( "min-width" in normalizedOptions ) {
        normalizedOptions.minWidth = normalizedOptions['min-width'];
        delete normalizedOptions["min-width"];
    }

    if ("max-width" in normalizedOptions) {
        normalizedOptions.maxWidth = normalizedOptions["max-width"];
        delete normalizedOptions["max-width"];
    }


    return {
        ...defaults,
        ...normalizedOptions
    };
}

const autoSizeDirective = {
	inserted(el, binding) {
		let inputEl;

		if (el.nodeName == "INPUT") {
			inputEl = el;
		} else {
			inputEl = el.querySelector("input");

			if (!inputEl) {
				return false;
			}
        }
        
        const options = normalizeOptions(binding.value);

        inputEl.style.boxSizing = "content-box";
        inputEl.style.minWidth = options.minWidth;
        inputEl.style.maxWidth = options.maxWidth;


		const mimicEl = document.createElement("div");
		mimicEl.style.display = "inline-block";
        mimicEl.style.font = getStyle(inputEl, "font");
        mimicEl.style.textTransform = getStyle(inputEl, "text-transform");
        mimicEl.style.letterSpacing = getStyle(inputEl, "letter-spacing");

		inputEl.addEventListener("keydown", function() {
			setTimeout(setWidth.bind(null, inputEl, mimicEl));
        });

        inputEl.addEventListener('change', function ( ) {
            setWidth(inputEl, mimicEl);
        });
        
        el.theMimicEl = mimicEl;

		document.body.appendChild(mimicEl);
		setWidth(inputEl,...