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...