JSFiddle - React, Tailwind, and code Playground

by Michael Prosser

HTML

<h1>Immersive Components Library</h1>
<ul>
  <li>
    <strong>Vector3</strong> works for properties like position,rotation,scaling
  </li>
  <li>
    <strong>Color3</strong> works for color properties where RGB components are
    needed
  </li>
  <li>
    <strong>Boolean</strong> works for boolean properties using a checkbox
  </li>
</ul>

CSS

body {
  font-family: helvetica;
}

.vector-component {
  font-size: 10px;
  width: 182px;
  margin-bottom: 6px;
}
.vector-component > h3 {
  margin-bottom: 3px;
  margin-top: 2px;
}
.vector-component > label {
  display: inline-block;
}
.vector-component[data-type="Vector3"] > label {
  width: 10px;
}
.vector-component[data-type="Color3"] > label {
  width: 10px;
}
.vector-component[data-type="Boolean"] > label {
  font-weight: bold;
  cursor: pointer;
}
.vector-component[data-type="Boolean"] > label > input {
  display: inline-block;
  vertical-align: middle;
  transform: scale(1.5);
  cursor: pointer;
  margin-left: 8px;
  margin-right: 8px;
}
.vector-component > h3 > input[type="color"] {
  outline: none;
  padding: 0;
  outline-offset: 0;
  border: none;
  vertical-align: middle;
  width: 100%;
  margin: 0;
  height: 15px;
  display: block;
}
.vector-component > input[type="number"] {
  width: 36px;
  font-size: 10px;
  margin-left: 3px;
  margin-right: 3px;
  border-radius: 4px;
  border: solid 1px #ccc;
  padding: 3px;
}

JavaScript

class ImmersiveComponent {

  constructor(type, label, object, parent) {
  
    this.component = document.createElement("div")

    this.component.classList.add("vector-component")
    this.component.setAttribute("data-type", type)

    this.inputs = []

    let component_label

    switch (type) {
      case "Vector3":
        component_label = document.createElement("h3")

        component_label.innerText = label

        let x_component = document.createElement("input")
        let y_component = document.createElement("input")
        let z_component = document.createElement("input")

        this.inputs.push(x_component)
        this.inputs.push(y_component)
        this.inputs.push(z_component)

        x_component.value = object.x
        y_component.value = object.y
        z_component.value = object.z

        let x_label = document.createElement("label")
        let y_label = document.createElement("label")
        let z_label = document.createElement("label")

        x_component.setAttribute("type", "number")
        y_component.setAttribute("type", "number")
        z_component.setAttribute("type", "number")

        x_label.innerText = "X:"
        y_label.innerText = "Y:"
        z_label.innerText = "Z:"

        this.component.appendChild(component_label)
        this.component.appendChild(x_label)
        this.component.appendChild(x_component)
        this.component.appendChild(y_label)
        this.component.appendChild(y_component)
        this.component.appendChild(z_label)
        this.component.appendChild(z_component)

        parent.appendChild(this.component)

        x_component.addEventListener("change", () => {
          object.x = parseFloat(x_component.value)
        })

        y_component.addEventListener("change", () => {
          object.y = parseFloat(y_component.value)
        })

        z_component.addEventListener("change", () => {
          object.z =...