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

@texaryn/web-components

v0.4.2

Published

A <texaryn-form> custom element over the Texaryn runtime, with native default widgets

Readme

@texaryn/web-components

A <texaryn-form> custom element for Texaryn, rendering native form controls in light DOM. Usable from any framework, or from none.

Status: pre-1.0. Public APIs may change before 1.0.

Install

pnpm add @texaryn/core @texaryn/schema-json @texaryn/web-components

The package depends on @texaryn/core only. It has no framework dependency and loads no stylesheet.

Quick start

Registration is explicit, so importing the package defines nothing on its own:

import { createJsonSchemaAdapter } from '@texaryn/schema-json'
import { createDefaultRegistry, defineTexarynForm } from '@texaryn/web-components'
import type { TexarynFormElement } from '@texaryn/web-components'

defineTexarynForm()

const port = await createJsonSchemaAdapter({
  type: 'object',
  properties: { name: { type: 'string', title: 'Name' } },
  required: ['name'],
})

const form = document.createElement('texaryn-form') as TexarynFormElement
form.registry = createDefaultRegistry()
form.errorSummary = true
form.options = { initialData: { name: '' }, onSubmit: (data) => console.log(data) }
form.port = port
document.body.append(form)

Two ownership modes

The element either creates a runtime or borrows one, and the two are mutually exclusive: setting both throws.

  • port plus options is the managed mode. The element creates a runtime and destroys it when the element is removed from the document. options is read when that runtime is created, so set it before port; setting port again rebuilds the runtime with the current options.
  • runtime is the primitive input. A runtime assigned this way is borrowed and never destroyed by the element, which is what lets an application own one runtime and render it through several bindings.

Being removed from the document is not the same as being discarded. Moving the element between parents fires disconnectedCallback too, so disposal is deferred and skipped if the element is connected again, and a reparent keeps the runtime, the controls and their values.

Events

Native events are left alone. The controls are real elements in light DOM, so input, change and blur bubble on their own. The element adds only its own namespaced events, each carrying a store snapshot as detail:

  • texaryn-data-change, the current form data
  • texaryn-submission-change, the current submission state

Submission

The element renders one <form novalidate> and turns its submit event into the Submit command, so a type="submit" button placed inside the form works the way a consumer expects. The runtime owns validation, which is why the native novalidate is set and required fields carry aria-required rather than the native required attribute.

Ids

Every id is <prefix>-<nodeId>-<suffix>, where the prefix is the element's own id attribute when it has one and an allocated value otherwise. Two forms on one page therefore share no ids, and every for and aria-describedby resolves inside its own element.

Messages

messages on the element, or in mountForm's options, takes a whole FormMessages set from @texaryn/core and replaces every word the built-in widgets invent. Setting it on a mounted element switches the copy in place. Custom widgets read ctx.messages on the render context.

Error summary

mountErrorSummary(container, form, { focus }) renders a named group, headed by an h2, listing the runtime's visible errors as the first child of container, and nothing while there are none. It takes the Mount that mountForm returned, so its links share the namespace the form was mounted under: #<prefix>-<nodeId>-input, the id the built-in widgets give their control, which a custom widget that wants summary navigation gives its own. It takes focus once a failed submit settles, once per attempt; focus: false keeps it passive, for all but one summary when one runtime is rendered twice. setMessages on the returned mount follows a locale switch in place, and unmounting the summary leaves the form mounted. A caller composing the two primitives calls setMessages on both mounts; the element does that for its own.

On the element, error-summary present mounts the summary as the first child of the element's <form> and error-summary="no-focus" mounts it passive; errorSummary and errorSummaryFocus reflect the attribute and its value. Toggling either applies live, and a value set while the element is detached applies when it next mounts. The summary is not a live region: the fields already announce their own errors, and the focus move is what speaks the heading.

Key exports

  • defineTexarynForm
  • TexarynFormElement
  • createDefaultRegistry
  • mountForm(container, runtime, { registry, idPrefix, messages }), returning a Mount carrying runtime, idPrefix and setMessages
  • mountErrorSummary(container, form, { focus }), returning an ErrorSummaryMount with setMessages
  • makeId
  • textInput, numberInput, checkbox, select, textarea
  • objectLayout, arrayControl
  • types: DomWidget, WidgetFactory, NodeBinding, RenderContext, Mount, ErrorSummaryOptions, ErrorSummaryMount

Not in this release

Shadow DOM, formAssociated and ElementInternals, nesting inside another <form>, group and layout containers beyond objects and arrays, and text and action nodes.

Related packages

See the repository README for the complete architecture.

License

Apache-2.0