JSFiddle - React, Tailwind, and code Playground

by anzeo

HTML

<div data-bind="spinner: nr, step: 0.2, precision: 5"></div>

CSS

.icon-minus:before{
    content: '-';
}

.icon-plus:before{
    content: '+';
}

JavaScript

function tryParse(n) {
    n = String(n).replace(',', '.');
    var parsed = parseFloat(n);
    return (!isNaN(parsed) && isFinite(n)) ? parsed : false;
}

function getPrecision(float){
    var a = (float + "").split('.');
    return a[1] ? a[1].length : 0;
}

ko.bindingHandlers.decimal = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor();
        if(!options.hasOwnProperty('precision')){
           options.precision = 2;
        }
        ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor);
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        var newValObs = valueAccessor(),
            newVal = ko.utils.unwrapObservable(newValObs);
        
        if ((newVal || newVal === 0) && (!newVal.isEnabled || newVal.isEnabled())) {
            var parsed = tryParse(newVal);
            if (parsed) {
                newValObs(parsed.toFixed(allBindingsAccessor().precision));
            } else {
                newValObs(0);
            }
            
        } else {
            newValObs(undefined);
        }
        ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor);
    }
};

ko.bindingHandlers.spinner = {
		init: function (element, valueAccessor, allBindingsAccessor) {
			var value = valueAccessor(),
			    options = allBindingsAccessor(),
				input = document.createElement('input'),
				decrementButton = document.createElement('button'),
				incrementButton = document.createElement('button'),
                step = options.step || 1,
                precision = options.precision || getPrecision(step);

			element.className += " ivanhoe-spinner";
			decrementButton.className = "icon-minus";
			incrementButton.className = "icon-plus";
			
			// set placeholder if declared
			if (options.spinnerPlaceholder) {
				input.setAttribute('data-i18n', '[placeholder]' + options.spinnerPlaceholder);
			}
           ...