New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@lit-labs/forms

Package Overview
Dependencies
Maintainers
11
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lit-labs/forms

Form helpers for Lit

latest
Source
npmnpm
Version
0.1.0
Version published
Weekly downloads
16
100%
Maintainers
11
Weekly downloads
 
Created
Source

@lit-labs/forms

A library for building form-associated custom elements with Lit.

Build Status Published on npm Join our Discord

[!WARNING]

This package is part of Lit Labs. It is published in order to get feedback on the design and may receive breaking changes or stop being supported.

Please read our Lit Labs documentation before using this library in production.

Installation

From inside your project folder, run:

$ npm install @lit-labs/forms

Form-associated custom elements are web components that participate in form submission, validation, and state restoration, just like built-in form elements. @lit-labs/forms helps builds correct form-associated custom elements by setting the proper ARIA roles, form value, disabled state, and more.

This package provides:

  • FormControl: A class mixin that makes it easy to build form associated custom elements that implement the standard form control APIs.
  • FormAssociated: A lower-level class mixin that only helps with form association, but doesn't add any public APIs.
  • Decorators: Decorators for binding properties to form values and state.

FormControl mixin

The FormControl mixin adds standard form-related public API properties and methods to a custom element. It also enables the use of decorators that let developers easily bind class fields to the form value and manage form state for restoration.

[!NOTE]

FormControl extends the FormAssociated mixin, which handles the ElementInternals integration and enables the decorators, but doesn't add any public API to the class.

It's recommended that most developers use FormControl instead of FormAssociated in order to add the idiomatic API that users expect from form controls (like .disabled, .form, .checkValidity(), etc.). Use FormAssociated only if you need to implement a completely custom API surface.

Example

import {LitElement, html} from 'lit';
import {customElement} from 'lit/decorators.js';
import {FormControl, formValue} from '@lit-labs/forms';

@customElement('simple-input')
export class SimpleInput extends FormControl(LitElement) {
  @formValue()
  accessor value = '';

  override render() {
    return html`
      <input
        .value=${this.value}
        @input=${(e: Event) =>
          (this.value = (e.target as HTMLInputElement).value)}
      />
    `;
  }
}

The added fields and methods mimic native form controls, providing a familiar API:

  • form: a readonly property that returns the associated form element.
  • labels: a readonly property that returns the labels associated with the element.
  • name: a read/write property that reflects the name attribute.
  • disabled: a read/write property that reflects the disabled attribute.
  • validity: a readonly property that returns the ValidityState of the element.
  • validationMessage: a readonly property that returns the error message that would be shown to the user if the element was to be checked for validity.
  • willValidate: a readonly property that returns true if internals' target element will be validated when the form is submitted. For example, disabled or hidden elements are not validated.
  • checkValidity(): If the element is invalid, returns false and fires an invalid event.
  • reportValidity(): Like checkValidity() but also shows the validation message to the user.

FormAssociated mixin

The FormAssociated mixin helps define a form-associated custom element.

FormAssociated creates a new form-associated base class and implements a number of best-practice behaviors for form-associated elements:

  • Sets the element's ARIA role using internals.role.
  • Updates the element's form value and state using internals.setFormState().
  • Saves the initial form value and state for use with form reset and restore.
  • Implements form reset via formResetCallback().
  • Implements form state restoration via formStateRestoreCallback().
  • Syncs the disabled state to internals.ariaDisabled via formDisabledCallback().
  • Calls the element's custom validator method, _getValidity(), when the form value changes and updates internals.setValidity() with the result.

FormAssociated doesn't add any public API to the element. Its behavior can be controlled with the decorators described below.

Decorators

@formValue()

The form value can be stored in any class field decorated with @formValue.

  @formValue()
  accessor value = '';

By default, the field must be of type string | File | FormData | null. If your element has a value of a different type, you can use a custom form value converter:

  @formValue({
    converter: {
      toFormValue(value: number) {
        return String(value);
      },
      fromFormValue(value: string) {
        return Number(value);
      },
    },
  })
  accessor value = 23;

@formStateGetter(), @formStateSetter(), and @formState()

Form state is additional data stored by the browser alongside the form value. While the form value is what gets submitted to the server, the form state is used to restore the element's user interface when the user navigates back or forward, or when the browser restores a session.

The underlying browser API is ElementInternals.setFormValue(value, state). The FormAssociated mixin automatically calls this method whenever the @formValue property changes. If you provide form state, it is passed as the second argument.

When the browser restores the element, FormAssociated receives the stored state and uses it to reset the element's properties.

To provide this state, you can use the @formState decorator on a property, or @formStateGetter and @formStateSetter on methods.

The @formState() decorator marks a field as being part of the form state. Its value will be included in the state passed to internals.setFormValue().

@formStateGetter() and @formStateSetter() allow for more complex state handling. They are applied to methods called to get or set the form state. The @formStateGetter() decorated method is called to retrieve the state object to pass to internals.setFormValue(). The @formStateSetter() decorated method is called with the restored state object when the browser restores the element.

class CustomStateElement extends FormAssociated(LitElement) {
  @formValue()
  accessor value = 'bar';

  @formState()
  @property()
  accessor count = 0;

  @formStateGetter()
  // @ts-expect-error #getFormState is called dynamically
  #getFormState() {
    return this.value + '#' + this.count;
  }

  @formStateSetter()
  // @ts-expect-error #setFormState is called dynamically
  #setFormState(state: string) {
    const [value, count] = state.split('#');
    this.value = value;
    this.count = Number(count);
  }
}

[!WARNING]

TypeScript will complain that a private getter isn't called even if it's decorated and called by the decorator. The FormAssociated API might change so that it doesn't require a @ts-expect-error comment to suppress this warning.

Utilities

  • isDisabled(): An element can be disabled because its ancestor fieldset is disabled, so checking the disabled attribute is insufficient. isDisabled() checks if the element matches :disabled, correctly handling inherited disabled state.

    import {isDisabled} from '@lit-labs/forms';
    

Contributing

Please see CONTRIBUTING.md.

FAQs

Package last updated on 23 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts