Skip to content

Instantly share code, notes, and snippets.

@yehuthi
Last active December 10, 2021 12:00
Show Gist options
  • Save yehuthi/89e2c0dae6155fc34db522c61bf0d6ae to your computer and use it in GitHub Desktop.
Save yehuthi/89e2c0dae6155fc34db522c61bf0d6ae to your computer and use it in GitHub Desktop.
export default function (input: HTMLInputElement): { destroy: () => void } {
const ctx = document.createElement('canvas').getContext('2d')!;
ctx.font = window.getComputedStyle(input).font;
function handler() {
input.style.width = `${ctx.measureText(input.value).width}px`;
}
input.addEventListener('input', handler as any);
handler();
return {
destroy: () => input.removeEventListener('input', handler as any),
};
}
const fontProps = [
'fontFamily',
'fontSize',
'fontStretch',
'fontStyle',
'fontVariant',
'fontWeight',
] as const;
export default function (input: HTMLInputElement): { destroy: () => void } {
const proxy = document.createElement('span');
proxy.style.position = 'fixed';
proxy.style.opacity = '0';
proxy.style.pointerEvents = 'none';
input.parentNode!.appendChild(proxy);
function handler() {
const computedStyle = window.getComputedStyle(input);
// We don't just always set the font because Firefox doesn't compound all font data into it.
if (computedStyle.font) proxy.style.font = computedStyle.font;
else for (const prop of fontProps) proxy.style[prop] = computedStyle[prop];
proxy.textContent = input.value;
input.style.width = `${proxy.clientWidth}px`;
}
input.addEventListener('input', handler as any);
setTimeout(handler);
return {
destroy: () => {
input.removeEventListener('input', handler as any);
proxy.parentNode!.removeChild(proxy);
},
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment