JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<div data-bind="with:pctInput">
<label>Value</label>
<input class="activeInput" data-bind='textInput: base, event:{blur:toggle}, visible:editing, hasFocus:editing' />
<input data-bind='textInput: formatted, event:{focus:toggle}, visible:!editing()' readonly='true' />
</div>

<div data-bind="with:commaInput">
<label>Another Value</label>
<input class="activeInput" data-bind='textInput: base, event:{blur:toggle}, visible:editing, hasFocus:editing' />
<input data-bind='textInput: formatted, event:{focus:toggle}, visible:!editing()' readonly='true' />

CSS

.activeInput { background-color: #fee; }

JavaScript

function editableFormatted(formatFn) {
    var self = {
        base: ko.observable(''),
        editing: ko.observable(false)
    };
    self.formatted = ko.computed(function () {
        return formatFn(self.base());
    });
    self.toggle = function() {
        self.editing(!self.editing());
    };
    return self;
}

function formatPct(num) {
    return num === '' ? '' : num + '%';
}

function formatCommas(num) {
    var formatted = num.replace(/\B(?=(\d{3})+$)/g, ',');
    console.debug("Formatted:", formatted);
    return formatted;
}

var viewModel = {
    pctInput: editableFormatted(formatPct),
    commaInput: editableFormatted(formatCommas)
};

ko.applyBindings(viewModel);