JSFiddle - React, Tailwind, and code Playground
by lid0
HTML
Auto size input with password support.
<div id="app">
<div>
Reference <input value="webkit: • FF: ●" disabled>
</div>
<input ref="myInput" class="myInput" v-model="value" :type="isPassword?'password':'input'"
:style="`width:${width}px;
min-width:${minWidth}px;
max-width:${maxWidth}px;
font-size:${fontSize}px;
font-weight:${fontWeight};
font-family:${fontFamily}
`" @input="onInput($event)"
:class= "{largerFont: useLargerFont}"
/>
<button @click="togglePassword">
toggle password
</button>
</div>
CSS
.myInput {
font-family:sans-serif;
}
.largerFont {
font-size:20px !important;
}
Vue
// author lidlanca 2021 april 7
calculateTextWidth = (value, font = "normal 400 14px sans-serif") => {
if (!calculateTextWidth.canvas) {
calculateTextWidth.canvas = document.createElement('canvas')
}
const canvas = calculateTextWidth.canvas
const context = canvas.getContext('2d')
context.font = font
const metrics = context.measureText(value)
return metrics.width
}
new Vue({
el: '#app',
data: {
inputComputedStyle: null, // computed style for input element
width: 30,
minWidth: 30,
maxWidth:300,
extraWidth:5,
fontSize: 14,
fontWeight: 400,
fontFamily: "sans-serif",
useDynamicFont:false,
value: "123",
isPassword: false,
passwordChar: (typeof InstallTrigger !== 'undefined') ? "●" : "•",
useLargerFont:false
},
methods: {
refreshComputedStyle(){
this.inputComputedStyle = window.getComputedStyle(this.$refs.myInput)
},
recalc() {
// webkit •
// ff ●
var str = this.value
if(this.isPassword){
// generate string in length with password char
str = Array(str.length + 1).join(this.passwordChar);
}
if(this.useDynamicFont){
this.refreshComputedStyle();
}
var cs = this.inputComputedStyle
// construct font definition from the input computed style properties.
// format: normal 400 14px sans-serif
var font = `${cs['font-style']} ${cs['font-weight']} ${cs['font-size']} ${cs['font-family']}`
/* console.log("FONT",font)
console.log("FONT2",cs) */
this.width = calculateTextWidth(str, font) + this.extraWidth
},
togglePassword() {
this.isPassword = !this.isPassword
this.inputComputedStyle = window.getComputedStyle(this.$refs.myInput)
this.recalc()
},
onInput() {
// changing the font-size dynamically is just to show how recalc
// properly adjust based on computed input style. when...