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

@adia-ai/web-components

v0.4.3

Published

AdiaUI web components — vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-runtime.

Readme

@adia-ai/web-components

Vanilla web components + A2UI runtime for AdiaUI. 80 light-DOM custom elements, a reactive core, a trait system, and a renderer that turns A2UI protocol messages into live DOM.

This package ships UI atoms only. The generation pipeline lives in @adia-ai/a2ui-compose; the pattern corpus in @adia-ai/a2ui-corpus; the MCP server in @adia-ai/a2ui-mcp.

Install

npm install @adia-ai/web-components

For composite shells (admin / chat / editor / simple / theme clusters), pair with @adia-ai/web-modules:

npm install @adia-ai/web-components @adia-ai/web-modules

Quick start

<link rel="stylesheet" href="node_modules/@adia-ai/web-components/index.css" />

<script type="module">
  import '@adia-ai/web-components';   // registers every *-ui tag
</script>

<card-ui>
  <header>
    <span slot="icon"><avatar-ui icon="user"></avatar-ui></span>
    <span slot="heading"><text-ui strong>Hello</text-ui></span>
  </header>
  <section>Composition works out of the box — no framework.</section>
</card-ui>

The package sideEffects entry keeps the import above from being tree-shaken; importing index.js side-effect-registers every component.

Layout

web-components/
├── core/           — Reactivity + base classes
│   ├── signals.js       signal() / computed() / effect() / batch() / untracked()
│   ├── template.js      tagged templates: html, css, repeat, stamp
│   ├── element.js       AdiaElement — light-DOM reactive base
│   ├── form.js          AdiaFormElement — form-associated + validation
│   ├── provider.js      global provider registration + router-ui
│   ├── anchor.js        popover + anchor-positioning
│   ├── markdown.js      lightweight markdown renderer
│   ├── transport.js     SSE / streaming helpers for LLM adapters
│   └── data-stream.js   `data-stream-*` attribute trait (HTTP/SSE/WS,
│                        signal-backed, refcounted shared transports)
│
├── components/     — 80 *-ui custom elements (primitives)
│   └── <tag>/
│       ├── <tag>.js       class definition (extends AdiaElement)
│       ├── <tag>.css      @scope(tag-ui) two-block: tokens + styles
│       ├── <tag>.yaml     authoring contract (props, slots, events, examples)
│       └── <tag>.a2ui.json  generated — do NOT edit
│
│  Composite elements (app-shell, app-nav*, adia-chat, adia-editor,
│  gen-ui, a2ui-root) ship in the sibling `@adia-ai/web-modules`
│  package as of 0.0.29 — see ADR-0012 for the three-tier rationale.
│
├── traits/         — 41 composable behaviors via defineTrait() + the
│                     <traits-host> wrapper for raw-HTML declarative
│                     composition. Generated catalog at _catalog.json
│                     drives the MCP get_traits tool + per-trait demo
│                     pages. Full contract in docs/specs/traits.md.
│
├── a2ui/           — deprecation shim for one release
│   └── index.js            Re-exports @adia-ai/a2ui-runtime with a
│                           one-time console.warn. Removed in 0.1.0.
│                           All actual A2UI runtime code (renderer,
│                           registry, streams, surface manifest,
│                           wiring, dockables, controllers) lives in
│                           `@adia-ai/a2ui-runtime` at packages/a2ui/runtime/.
│
└── styles/         — Global tokens and CSS layering
    ├── tokens.css              all --a-* design tokens
    ├── colors/                 primitives / semantics / scrims
    ├── typography.css, space.css, radius.css, shadow.css
    └── themes/*.css            8 themes (ocean, forest, sunset, …)

Build + dev utilities (including build-a2ui-data.mjs, qa-training.mjs, a2ui-to-html.cjs, mcp-call.cjs, mcp-pipeline.cjs, screenshot.cjs) live at the repo-root scripts/ directory rather than inside this package — they span the monorepo (MCP server, a2ui-corpus data, component catalog) and aren't scoped to web-components alone.

Component contract

Every component is a single-file class extending AdiaElement (or AdiaFormElement for form fields). All styling lives in a sibling .css file using two-block @scope:

@scope (button-ui) {
  :where(:scope) {
    /* Tokens only — zero specificity, parent overrides win */
    --button-bg:     var(--a-accent-bg);
    --button-fg:     var(--a-accent-fg);
    --button-radius: var(--a-radius);
  }
  :scope {
    /* Styles — consume component tokens only, never global directly */
    background: var(--button-bg);
    color:      var(--button-fg);
    border-radius: var(--button-radius);
  }
  :scope[variant="danger"] {
    --button-bg: var(--a-danger-bg);   /* variants override tokens, not styles */
  }
}

Authoring rules (enforced by ui-audit-coherence):

  1. No raw colors in component CSS — every color goes through a token.
  2. Variants change tokens, modes change layout. A selector that sets display, padding, flex, grid, etc. is a mode and needs a Sanctioned Mode Attributes entry in the contract doc.
  3. Boolean props default to false. If the expected default is "on", flip the name (closablepermanent).
  4. Event listeners in connected() have matching removeEventListener in disconnected(). Handlers are stable #field arrows, never inline.
  5. Light DOM only. No ::part(), ::slotted(), shadow roots. Use attribute selectors on children: :scope > [slot="icon"].

Full authoring contract: docs/specs/component-token-contract.md. The adia-ui-author skill encodes the 20 non-negotiable rules.

Card-n / drawer-ui composition parity

Both accept bare <header> / <section> / <footer> tags OR explicit [slot="header|body|footer"]. Both activate a 3-column header grid when any direct [slot="icon|heading|description|action"] child is present (:has(> …) — direct-child only). Drawer supports multi-section bodies with sticky header/footer. See the drawer component page for worked examples.

A2UI runtime

import { A2UIRenderer } from '@adia-ai/a2ui-runtime';
// (The old `@adia-ai/web-components/a2ui` subpath still resolves in 0.0.4
// via a deprecation shim that prints a console.warn; removed in 0.1.0.)

const renderer = new A2UIRenderer({ target: document.getElementById('canvas') });
renderer.apply({
  type: 'updateComponents',
  components: [
    { id: 'root', component: 'Card', children: ['hdr', 'body'] },
    { id: 'hdr',  component: 'Header', slots: { heading: 'Generated UI' } },
    { id: 'body', component: 'Section', children: ['btn'] },
    { id: 'btn',  component: 'Button', attrs: { variant: 'primary' }, content: 'Click' },
  ],
});

Accepts the four A2UI message kinds: updateComponents, updateDataModel, wireComponents, createSurface. The registry normalizes LLM-emitted aliases (e.g. Carouselswiper-ui) so generated output is robust to name drift.

Data streaming via data-stream-* attributes

Any element with a settable .data property — chart-ui, table-ui, heatmap-ui, stat-ui, list-ui, etc. — can be fed from a backing source via attributes alone. No per-component opt-in:

<!-- HTTP one-shot fetch, JSON -->
<chart-ui type="area" x="month" y="revenue"
          data-stream-src="/api/revenue?range=3m"
          data-stream-path="data"></chart-ui>

<!-- HTTP polling every 5s -->
<table-ui sortable striped
          data-stream-src="/api/orders"
          data-stream-interval="5000"></table-ui>

<!-- Server-Sent Events, append on each message -->
<heatmap-ui type="matrix" rows="7" cols="52"
            data-stream-src="/sse/activity"
            data-stream-mode="sse"
            data-stream-merge="append"></heatmap-ui>

<!-- Spread a multi-property response onto the element -->
<stat-ui data-stream-src="/api/kpi"
         data-stream-target="*"></stat-ui>

Modes: HTTP (one-shot or polling), sse (EventSource), ws (WebSocket). Formats: json (default), csv, tsv, jsonl, text — auto-detected from URL extension or content-type. Two elements with attribute-identical streams share one transport (refcounted, signal-backed); explicit data-stream-id lets unrelated configs share intentionally. Programmatic access via the streams registry export from core/data-stream.js.

Implementation: core/data-stream.js (~360 lines). Full attribute table + live demos: /site/components/chart#data-stream.

Build

npm run build:components    # regenerate all .a2ui.json from YAML

The build also writes packages/a2ui/corpus/catalog-a2ui_0_9.json and catalog-a2ui_0_9_rules.txt — the flat-file catalog the MCP server and generation engine consume.

Themes, density, scale

<div data-theme="ocean" density="compact" size="sm">
  …all descendants re-theme / re-densify / re-scale automatically…
</div>
  • [data-theme] — 8 themes: default, ocean, forest, sunset, lavender, rose, slate, midnight
  • [density]compact (0.85×) · spacious (1.15×)
  • [size]sm|md|lg shifts the entire typescale + component dimensions
  • [radius]sharp (0) · rounded (1) · round (2)

Each is a CSS-variable override; no class toggles, no re-imports.

Dependency direction

a2ui-compose  ──reads──>  a2ui-corpus  ←─reads──  web-components
a2ui-mcp      ──reads──>  a2ui-compose, a2ui-corpus

Web-components never imports from a2ui-compose or a2ui-mcp. The A2UI renderer consumes a protocol, not a generator — anything that emits valid A2UI messages drives it.

License

MIT