JSFiddle - React, Tailwind, and code Playground

by Grax_

HTML

<div id="container">
  <div>
    <h1>General pattern</h1>
    <input type="text" id="generalInput" />
    <span>
      <p>Output:</p>
      <p id="generalOutput"></p>
    </span>
  </div>
  <div>
    <h1>Specific pattern</h1>
    <input type="text" id="specificInput" />
    <span>
      <p>Output:</p>
      <p id="specificOutput"></p>
    </span>
  </div>
</div>

CSS

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

body,
#container {
  display: flex;
  justify-content: space-evenly;
  align-items: center;
}

#container {
  width: 100%;
  flex-direction: row;
}

p {
  margin-top: 10px;
  font-size: 24px;
  min-height: 24px;
}

input,
input:focus-visible {
  font-size: 24px;
  border: 2px solid;
  outline: none;
}

.error {
  border-color: red;
  color: red;
}

.success {
  border-color: green;
  color: green;
}

JavaScript

const generalRegex =
  /^ ?(?:\d{1,3}[,. ](?=\d{3}))*?\d*(?:(?<=\d)|(?=[,.]\d))([,.])?\d* ?$/
const specificRegex =
  /^ ?(?:\d{1,3}[. ](?=\d{3}))*?\d*(?:(?<=\d)|(?=[,]\d))([,])?\d* ?$/

const generalIn = document.getElementById("generalInput")
const generalOut = document.getElementById("generalOutput")

const specificIn = document.getElementById("specificInput")
const specificOut = document.getElementById("specificOutput");

[generalIn, specificIn].forEach((input) => {
  input.addEventListener("input", (_) => {
    // Only allow numbers, commas, dots and spaces.
    // Disallow more than one comma, dot or space.
    input.value = input.value
      .replace(/[^\d,. ]/g, "")
      .replace(/([,. ]){2,}/g, "$1")
    const value = input.value.trim()

    if (input.id.includes("general")) {
      if (value === "" || generalRegex.test(value)) {
        input.classList.remove("error")
        generalOut.previousElementSibling.classList.remove("error")
        generalOut.classList.remove("error")

        input.classList.add("success")
        generalOut.previousElementSibling.classList.add("success")
        generalOut.classList.add("success")
      } else {
        input.classList.add("error")
        generalOut.previousElementSibling.classList.add("error")
        generalOut.classList.add("error")

        input.classList.remove("success")
        generalOut.previousElementSibling.classList.remove("success")
        generalOut.classList.remove("success")
      }
      generalOut.textContent = parseGeneralNumber(value)
    } else {
    	if (value === "" || specificRegex.test(value)) {
        input.classList.remove("error")
        specificOut.previousElementSibling.classList.remove("error")
        specificOut.classList.remove("error")

        input.classList.add("success")
        specificOut.previousElementSibling.classList.add("success")
        specificOut.classList.add("success")
      } else {
        input.classList.add("error")
       ...