npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jb-form

v0.12.0

Published

form web component with extended feature like validation and dirty check

Readme

jb-form

Published on webcomponents.org GitHub license NPM Version GitHub Created At

JB Design System form coordinator for validation, dirty checks, value collection, virtual fields, and nested forms.

  • Validates JB form controls with one command.
  • Tracks aggregate dirty state.
  • Gets and sets values for named child controls.
  • Supports native form controls, form-associated custom elements, virtual elements, and nested jb-form elements.
  • Dispatches submit, dirty-change, and validity-change events.

When to use

Use jb-form when a group of fields needs aggregate validation, value collection, dirty-state tracking, virtual fields, or nested form sections.

Use a native <form> when you only need browser-native submission and do not need JB aggregate helpers.

Demo

Using With JS Frameworks

Installation

npm i jb-form
import 'jb-form';
<jb-form>
  <jb-input name="name" required></jb-input>
  <jb-button type="submit">Submit</jb-button>
</jb-form>

API reference

Attributes

| name | type | default | description | | --- | --- | --- | --- | | name | string | "" | Name used when this form is nested inside another jb-form. |

Properties

| name | type | readonly | description | | --- | --- | --- | --- | | value | FormValues | no | Aggregated object of named child values. Setting it calls setFormValues(value). | | name | string | no | Name attribute value used by parent jb-form traversal. | | isDirty | boolean | yes | true when any named child control, virtual element, or sub-form is dirty. | | validation | ValidationHelper<FormValues> | yes | Aggregate jb-validation helper. | | validElements | HTMLElement[] | yes | Connected native and custom form controls registered directly under this jb-form. | | virtualElements | object | yes | Virtual element registry: list, dictionary, add(config), and remove({ virtualElement }). | | subForms | object | yes | Nested jb-form registry: list and dictionary. | | formElements | FormElements | yes | Internal native/custom child form element registry. |

Methods

| name | returns | description | | --- | --- | --- | | checkValidity() | boolean | Runs synchronous aggregate validation without showing errors. | | reportValidity() | boolean | Runs synchronous aggregate validation and asks children to show errors. | | jbCheckValidity({ showError }) | Promise<CheckValidityAsyncResult> | Runs rich async validation for jb-validation compatible children, virtual elements, and sub-forms. | | getValidationMessages() | FormValidationMessages | Returns validation messages for named child controls, virtual elements, and sub-forms. | | getValidationSummary() | FormValidationSummary | Returns validation summaries for named jb-validation compatible items. | | getValidationResult() | FormValidationResult | Returns full validation results for named jb-validation compatible items. | | getFormValues() | FormValues | Returns all named child values. Repeated names become TraverseCollection. | | getFormDirtyStatus() | TraverseResult<boolean> | Returns dirty status for named child controls, virtual elements, and sub-forms. | | setFormValues(value, shouldUpdateInitialValue?) | void | Sets values by name. Also updates initial values unless the second argument is false. | | setFormInitialValues(value, shouldUpdateValue?) | void | Sets initial values used for dirty checks. Also updates current values unless the second argument is false. | | reset() | void | Restores custom controls, native controls, virtual elements, and nested forms to their initial values and clears validation state. |

Events

| event | detail | description | | --- | --- | --- | | submit | none | Dispatched after a trusted child submit is intercepted and reportValidity() returns true. | | dirty-change | { isDirty: boolean } | Dispatched when aggregate dirty state changes. | | validity-change | { isValid: boolean } | Dispatched when aggregate synchronous validity changes. | | change | none | Dispatched by the form when a virtual element changes. Child controls may also bubble their own change events through jb-form. | | form-change | none | Dispatched from a child control when setFormValues() changes it programmatically. | | init | none | Dispatched from connectedCallback after child element scanning starts. | | disconnect | none | Dispatched from disconnectedCallback. |

Validation

Use checkValidity() for a silent synchronous check and reportValidity() to show child validation messages.

const form = document.querySelector('jb-form');

const isValid = form.checkValidity();
const isValidAndShown = form.reportValidity();

Use jbCheckValidity() when async validations are involved. It validates JB validation-compatible child controls, virtual elements, and sub-forms and returns a tree result with element references.

import { getInvalidElements } from 'jb-form';

const result = await form.jbCheckValidity({ showError: true });
const invalidElements = getInvalidElements(result);

Detailed validation helpers:

form.getValidationMessages();
form.getValidationSummary();
form.getValidationResult();

Value control

jb-form collects values from named direct child controls, virtual elements, and named sub-forms.

const form = document.querySelector('jb-form');

const values = form.getFormValues();

form.setFormValues({
  name: 'Joe',
  age: 10,
});

form.setFormValues({ name: 'Joe' }, false);

setFormValues(value) updates both value and initialValue by default. Pass false as the second argument when you only want to change current values.

form.setFormInitialValues({ name: 'Joe', age: 10 });
form.setFormInitialValues({ name: 'Joe' }, false);

Reset the complete form tree:

form.reset();

Dirty state

console.log(form.isDirty);
console.log(form.getFormDirtyStatus());

form.addEventListener('dirty-change', (event) => {
  console.log(event.detail.isDirty);
});

Submit

jb-form listens for trusted submit events from submit-capable child controls, prevents the original event, calls reportValidity(), and dispatches its own submit event when the form is valid.

form.addEventListener('submit', (event) => {
  event.preventDefault();
  console.log(form.getFormValues());
});

Virtual elements

Use virtual elements for state that is not represented by a JB/native form control but still needs to participate in form values, dirty checks, or validation.

import { ValidationHelper } from 'jb-validation';

const tagList = form.virtualElements.add({
  name: 'tags',
  validation: new ValidationHelper({
    getValue: () => tags,
    getValidations: () => [
      {
        validator: (value) => value.length > 0,
        message: 'Select at least one tag',
      },
    ],
  }),
  getValue: () => tags,
  getDirtyStatus: () => tags.length !== initialTags.length,
  setValue: (value) => {
    tags = value;
  },
  setInitialValue: (value) => {
    initialTags = value;
  },
  reset: () => {
    tags = [...initialTags];
  },
});

tagList.dispatchOnChange();

Remove a virtual element when it is no longer part of the form:

form.virtualElements.remove({ virtualElement: tagList });

Same-name values

When two or more named items share the same name, the value becomes a TraverseCollection, which extends Map and is marked with ValueCollectionSymbol.

<jb-form>
  <jb-input name="personName" value="Ali"></jb-input>
  <jb-input name="phoneNumber" value="1234"></jb-input>
  <jb-input name="phoneNumber" value="5678"></jb-input>
</jb-form>
const values = form.getFormValues();
console.log(values.phoneNumber instanceof Map); // true

If fields have id, the collection uses the id as the key; otherwise it uses numeric keys.

Sub forms

Nested jb-form elements can be managed individually and by a parent form.

<jb-form id="parentForm">
  <jb-form name="profile">
    <jb-input name="firstName"></jb-input>
  </jb-form>
  <jb-form name="security">
    <jb-input name="password"></jb-input>
  </jb-form>
</jb-form>
console.log(document.querySelector('#parentForm').getFormValues());

Slots and styling

jb-form has a default slot for child controls and layout content. It does not currently expose CSS parts or CSS variables.

Related Docs

AI agent notes

  • Import jb-form once before using <jb-form>.
  • Put fields inside the default slot and give each field a name if its value should be collected.
  • Use getFormValues() for aggregate values and setFormValues(values) to update children by name.
  • Use jbCheckValidity({ showError: true }) for async validation; checkValidity() and reportValidity() are synchronous.
  • Listen to submit, dirty-change, and validity-change for form workflows.
  • Repeated names return TraverseCollection, not a plain array.
  • Use virtualElements.add(config) for non-DOM or non-standard form state.
  • This package includes custom-elements.json and points to it with the package.json customElements field. The field is documented by the Custom Elements Manifest project in Referencing manifests from npm packages.
  • In custom-elements.json, exports.kind: "js" describes JavaScript/TypeScript exports and exports.kind: "custom-element-definition" maps the jb-form tag name to JBFormWebComponent.