trim text with multiple Web Components

by WebComponents

HTML

<script>
  // create Web Components for each trim type
  Object.entries({
    leading: (text) => text.replace(/^\s+/, ""),
    trailing: (text) => text.replace(/\s+$/, ""),
    both: (text) => text.replace(/^\s+|\s+$/g, ""),
    compress: (text) => text.replace(/\s+/g, " "),
  }).forEach(([trimType, trimFunc]) =>
    customElements.define(
      "trim-" + trimType,
      class extends HTMLElement {
        connectedCallback() {
          setTimeout(() => { // wait till lightDOM innerHTML is available
            let text = this.getAttribute("text") || this.innerHTML;
            let trimmed = trimFunc(text);
            this.innerHTML = trimmed;
            console.log( "trim", trimType, text, trimmed,
              text.length - trimmed.length, "chars" );
          }); // setTimeout
        } // connectedCallback
      }, // class
    ), // define Web Component
  ); // forEach
</script>

<!-- 
put the text in an attribute, the IDE sanitizes HTML removing whitespace
Web Component *does work* with text in lightDOM/innerHTML only, see below -->
<trim-leading text=" hello world "></trim-leading>
<trim-trailing text=" hello world "></trim-trailing>
<trim-both text=" hello world "></trim-both>
<trim-compress text="hello   world  !"></trim-compress>
<trim-compress text="  hi   there  ">HI THERE</trim-compress>

<script>
  // create DOM demonstrating trim components with text in lightDOM
  const createElement = (tag, props) => Object.assign(document.createElement(tag), props);
  Object.entries({
    leading: " Hello World ",
    trailing: " Hello World ",
    both: " Hello World ",
    compress: "   hello   world  !",
  }).forEach(([trimType, text]) => {
    let spaced = text.replace(/\s/g, "_");
    document.body.append(
      createElement("h3", { textContent: `<trim-${trimType}>` }),
      createElement("p", { textContent: `input: "${spaced}"` }),
      "output: ",
      `"`,
      createElement("trim-" + trimType, {
...