Vue

by joplomacedo

HTML

<div id="app">
  <number-input
    v-model="theNumber"
    :precision="1"
     :step="0.1"
    
    class="u-mb-2"
    :min="0"
    :max="10"
    
    
    ></number-input>
  <p>The number: {{theNumber}}</p>
  <button @click="up">Up</button>
</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);
}

.u-mb-2   {
  margin-bottom: 2em;
}

Vue

function isNonCharInsertingKey(e) {
  return (
    e.shiftKey ||
    e.altKey ||
    e.ctrlKey ||
    (e.metaKey && !e.ctrlKey) ||
    [8, 9, 13, 35, 36, 37, 39, 46, 45].includes(e.which)
  );
}


function attemptConvertStrToNum( str ) {
	//customizations
	if ( str === '.' ) {
  	return 0;
  }
  
  //default
	return +str;
}

function strIsOrCanBecomeValidNumber(str, { max, min, precision }) {
  
  //immediate disqualification
  if ( ( str.includes('.') && precision === 0) ||
    	 ( str.includes('-') && min >= 0 ) ) {
  	return false;
  }
  
  // we could just do a isNaN check on the number version
  // of the string, but that wouldnt work well with special cases
  // like "." , "-", "-." "-0" so we deal with those first
  
  //exceptions check
  if ( precision > 0 && min < 0) {
  	
    if ( str === '-0' ||
         str === '-.' ) {
      return true;
    }
  
  }
  
  if ( precision > 0 ) {
  	
    if ( str === '.' ) {
    	return true;
    }
    
  }
  
  if ( min < 0 ) {
  	
      if ( str === "-") {
        return true;
      }
  
  }
  
  //lets check with isNaN now
  if ( isNaN(str) ) {
    return false;
  }
	
  //its a valid string number. great. lets check if it works with
  // the options as a number
   const num = +str;
    
  if (num > max || num < min) {
    return false;
  }

  //is decimal
  if (getPrecision(num) > precision) {
    return false;
  }

  return true;
}

function getPrecision(num) {
  const decimalPart = ("" + num).split(".")[1];
  return decimalPart ? decimalPart.length : 0;
}

function inc(value, amount, max) {
  let maxPrecision = Math.max(getPrecision(value), getPrecision(amount));
  let x = +(value + amount).toFixed(maxPrecision);
  return Math.min(x, max);
}

function dec(value, amount, min) {
  let maxPrecision = Math.max(getPrecision(value), getPrecision(amount));
  let x = +(value - amount).toFixed(maxPrecision);
  return Math.max(x, min);
}

function getMaxCharsCount({ min, max, precision }) {
  let fromMax, fromMin;
  let...