web components formResetCallback() never triggers

82 Views Asked by At

I have a custom web components written using lit components and I am currently trying to make the it behave like a regular form input. After a bit of tinkering I have the whole attachInternals() thing figured out and have the input starting to behave right. Then I wanted to configure the reset behaviour of the input and saw that there is a callback function to handle this, but I can't for the life of me get the callback to trigger. To make sure that in my form the reset command was triggering correctly I added a normal <input> element which resets just fine. And to make sure I attached the internals correctly I added a formAssociatedCallback which also works just fine and is called on form attachment. This is my code:

import { LitElement, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import styles from "./styles.scss";

@customElement("flit-input")
export class FlitInput extends LitElement {
  public static readonly styles = styles;
  public static readonly formAssociated = true;

  @property({ type: String, reflect: true })
  name: string;

  @property({ type: String, reflect: true })
  type:
    | "checkbox"
    | "color"
    | "date"
    | "datetime-local"
    | "email"
    | "file"
    | "hidden"
    | "image"
    | "month"
    | "number"
    | "password"
    | "radio"
    | "range"
    | "search"
    | "tel"
    | "text"
    | "time"
    | "url"
    | "week" = "text";

  @property({ type: String, reflect: true })
  label: string = "";

  @property({ type: String, reflect: true })
  value?: string = "";

  @property({ type: Boolean })
  disabled: boolean = false;

  @state() private _internals: ElementInternals;

  private constructor() {
    super();
    this._internals = this.attachInternals();
    setTimeout(() => {
      this._internals.setFormValue(this.value);
    });
  }

  private handleInput(event: Event) {
    this.value = (event.target as HTMLInputElement).value;
    this._internals.setFormValue(this.value);
  }

  private handleChange(event: Event) {
    this.handleInput(event);
    this.dispatchEvent(new Event(event.type, event));
  }

  public formAssociatedCallback(form: HTMLFormElement) {
    console.log(form);
  }

  public formResetCallback() {
    console.log("ResetCallback");
  }

  render() {
    return html`
      <div id="wrapper">
        <div id="label">${this.label}</div>
        <input
          .value="${ifDefined(this.value)}"
          ${ifDefined(this.disabled)}
          type="${ifDefined(this.type)}"
          @input="${this.handleInput}"
          @change="${this.handleChange}"
        />
      </div>
    `;
  }
}
0

There are 0 best solutions below