vue-numero-input

by joplomacedo

HTML

<div id="app">

  <vue-numero-input v-model="theNumber" :min="0.5" :precision="2" :min="0" :max="20"></vue-numero-input>
  <div>
      val: {{ theNumber }}
  </div>
  <div>
      typeof val: {{ typeof theNumber }}
  </div>
</div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}

Vue

const isValidNumStr = (() => {
    const allowedChars = [
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        "0",
        ".",
        "-",
    ];

    return function ({ numStr, options: { max, min, precision } }) {
        //make sure it's a numstr
        numStr = "" + numStr;

        if (numStr.split("").some((char) => !allowedChars.includes(char))) {
            return false;
        }

        if (numStr.includes("-")) {
            if (min >= 0) {
                return false;
            }

            //if the minus isnt last char
            // (also covers existence of two minuses)
            if (numStr.lastIndexOf("-") !== 0) {
                return false;
            }
        }

        if (numStr.includes(".")) {
            if (precision == 0) {
                //includes dot and precison = 0
                return false;
            }

            if (numStr.split(".").length - 1 > 2) {
                //more than one dot
                return false;
            }

            const decimalPart = numStr.split(".")[1];

            if (decimalPart.length > precision) {
                //more decimals than allowed precison
                return false;
            }
        }
        
        
        if ( numStr == '') {
        	return true;
        }
        
        /*
        if ( numStr === '0.' || numStr === '.' && min > 0 && min < 1) {
        	return true;
        }
       */

        const num = +numStr;

        if (num < min) {
            return false;
        }

        if (num > max) {
            return false;
        }

        return true;
    };
})();

function convertNumStrToNum({numStr, defaultNum}) {
    if (numStr == '' || numStr === "." || numStr === "-." || numStr === "-") {
        return defaultNum;
    }

    return +numStr;
}

function getPrecisionFromNum(num) {
    const decimalPart = ("" + num).split(".")[1];
    return decimalPart ?...