<form>
  <rad-input name="radInput" required>First name</rad-input>
  <label for="basic">Basic input</label>
  <input value="foo" name="basic" id="basic">
  <button type="submit">Submit</button>
  
  <pre><output></output></pre>
</form>
:root {
  --primary-color: hsl(250, 100%, 25%);
  --text-color: #141414;
  --text-color-inverted: #ffffff;
}

pre {
  background: var(--primary-color);
  color: var(--text-color-inverted);
  font-family: "Operator Mono", "Fira Code", monospace;
  padding: 16px;
}
import { LitElement, html, css } from 'https://unpkg.com/lit-element?module';
import 'https://cdn.skypack.dev/element-internals-polyfill';

class RadInput extends LitElement {
  static get formAssociated() {
    return true;
  }
  
  static get properties() {
    return {
      name: { type: String, reflect: true },
      required: { type: Boolean, reflect: true },
      value: { type: String }
    };
  }
  
  static get styles() {
    return css`
    :host {
      display: block;
      font-family: system-ui;;
      margin: 0 0 16px;
    }
    label {
      color: #141414;
      display: block;
      font-size: 14px;
      margin-bottom: 8px;
    }
    input {
      border: 1px solid hsl(250, 100%, 25%);
      border-radius: 8px;
      color: #141414;
      font-size: 16px;
      padding: 8px;
    }
    `;
  }
  
  constructor() {
    super();
    this.internals = this.attachInternals();
    this.name = name;
    this.required = false;
    this.value = '';
    this._required = false;
  }
  
  render() {
    return html`
      <label for="input"><slot></slot></label>
      <input type="${this.type}" name="${this.name}" id="input" .value="${this.value}" ?required="${this.required}" @input="${this._onInput}">
    `;
  }
  
  _onInput(event) {
    this.value = event.target.value;
    this.internals.setFormValue(this.value);
  }
  
  /** LitElement lifecycle method */
  firstUpdated(...args) {
    super.firstUpdated(...args);
    /** This ensures our element always participates in the form */
    this.internals.setFormValue(this.value);
  }
}

customElements.define('rad-input', RadInput);

/** Get a reference to the form */
const form = document.querySelector('form');

/** Get the output element to display form data in */
const output = document.querySelector('output');

/** Prevent default on form submissions */
form.addEventListener('submit', event => {
  event.preventDefault();
  
  const form = event.target;
  console.log('Rad input:', form.radInput);

  /** Get all of the form data */
  const formData = new FormData(form);
  const data = {};
  formData.forEach((value, key) => data[key] = value);
  output.innerHTML = JSON.stringify(data, null, 2);
  console.log('rad value: ', document.querySelector('[name="radInput"]').value);
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.