<div id="app"></div>
import { LitElement, html, css } from 'https://cdn.skypack.dev/lit-element';
import React, { useRef, useEffect, useState } from 'https://cdn.skypack.dev/react';
import ReactDOM from 'https://cdn.skypack.dev/react-dom';

function App() {
  const coolInput = useRef();
  const [coolInputValue, setCoolInputValue] = useState('');
  
  function eventListener(event) {
    const value = event.detail;
    setCoolInputValue(value);
    
    if (value.toLowerCase() === 'rad') {
      coolInput.current.reportValue();
    } 
  }
  
  useEffect(() => {
    coolInput.current.addEventListener('custom-input', eventListener);
    
    return () => {
      coolInput.current.removeEventListener('custom-input', eventListener);
    }
  });
  
  return <div>
    <h1>My totally righteous form</h1>
    <pre>CoolInputValue: {coolInputValue}</pre>
    <form>
      <super-cool-input 
        ref={coolInput}
        label="The first question"
      ></super-cool-input>
    </form>
  </div>;
}

class SuperCoolInput extends LitElement {
  static properties = {
    label: { type: String, reflect: true },
    type: { type: String, reflect: true }
  };
  
  static styles = css`
    :host {
      display: block;
      --local-stack: "Helvetica Neue", Arial, sans-serif;
    }
    label {
      display: block;
      font-size: 16px;
      font-family: var(--x-font-stack, var(--local-stack));
      margin-block-end: 12px;
    }
    input {
      border-radius: var(--x-border-radius, 4px);
      font-size: var(--x-font-size, 16px);
      padding-block: var(--x-padding-block, 12px);
      padding-inline: var(--x-padding-inline, 8px);
    }
  `;

  type = 'text';

  render() {
    return html`
    <label for="input">${this.label}</label>
    <input type="${this.type}" @input="${this._emit}" id="input">`;
  }

  _emit(event) {
    const e = new CustomEvent('custom-input', {
      detail: event.target.value
    });

    this.dispatchEvent(e);
  }
  
  reportValue() {
    alert(this.shadowRoot.querySelector('input').value);
  }
}

customElements.define('super-cool-input', SuperCoolInput);

ReactDOM.render(<App />, document.getElementById('app'));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.