JSFiddle - React, Tailwind, and code Playground

by dandclark_msft

HTML

<!doctype html>
<html>
<head>
  <title>Select experiments</title>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    class MyCustomSelect extends HTMLSelectElement {
      constructor() {
          super();
      }

      // Intercept calls to set value in order to update the View, then forward to
      // HTMLSelectElement base class.  Can be done for other view-impacting properties as well.
      set value(newValue) {
          let li = document.createElement("li");
          li.innerText = `set value to ${newValue}`;
          document.getElementById("log").append(li);
          
          super.value = newValue;

          // Queue update to the View here.
      }

      // Example of how the derived class can include default light-DOM content to be slotted
      // into the custom <select>.  Here it's just <option>s but in the future this could
      // be the custom <select> UI. 
      connectedCallback() {
        let option0 = document.createElement("option");
        let option1 = document.createElement("option");
        option0.innerHTML = "This is a default option.  A framework could add this.";
        option1.innerHTML = "For a custom select a framework could also provide custom UI to be slotted in.";
        this.append(option0, option1)
      }

      // This approach doesn't work for intercepting select.value = 'foo' since this only watches content attributes.
      attributeChangedCallback(name, oldValue, newValue) {
        console.log(`attributeChangedCallback ${name} set to ${newValue}`);
      }
      static get observedAttributes() {
        return ["value"];
      }
    }
    window.customElements.define("custom-select", MyCustomSelect, { extends: "select" });
    
    function changeSelectValue() {
    	document.querySelector("select").value = "thing 2";
    }
  </script>
    <select is="custom-select">
      <option>thing 1</option>
      <option>thing 2</option>
    </select>
    <input type="button" value="Click to change...