JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 48
  • Score
    100M100P100Q106146F
  • License MIT

Light-DOM custom elements, tokens, traits, patterns, and an A2UI-compatible pattern (nano-a2ui-root). A2UI runtime itself lives in @nano-ui-kit/a2ui-utils.

Package Exports

  • @nano-ui-kit/web-components
  • @nano-ui-kit/web-components/components
  • @nano-ui-kit/web-components/components/accordion
  • @nano-ui-kit/web-components/components/action-list
  • @nano-ui-kit/web-components/components/agent-artifact
  • @nano-ui-kit/web-components/components/agent-feedback-bar
  • @nano-ui-kit/web-components/components/agent-questions
  • @nano-ui-kit/web-components/components/agent-reasoning
  • @nano-ui-kit/web-components/components/agent-suggestions
  • @nano-ui-kit/web-components/components/agent-trace
  • @nano-ui-kit/web-components/components/alert
  • @nano-ui-kit/web-components/components/avatar
  • @nano-ui-kit/web-components/components/badge
  • @nano-ui-kit/web-components/components/block
  • @nano-ui-kit/web-components/components/breadcrumb
  • @nano-ui-kit/web-components/components/button
  • @nano-ui-kit/web-components/components/calendar-picker
  • @nano-ui-kit/web-components/components/canvas
  • @nano-ui-kit/web-components/components/card
  • @nano-ui-kit/web-components/components/chart
  • @nano-ui-kit/web-components/components/chat
  • @nano-ui-kit/web-components/components/check
  • @nano-ui-kit/web-components/components/code
  • @nano-ui-kit/web-components/components/col
  • @nano-ui-kit/web-components/components/color-picker
  • @nano-ui-kit/web-components/components/command
  • @nano-ui-kit/web-components/components/description-list
  • @nano-ui-kit/web-components/components/divider
  • @nano-ui-kit/web-components/components/drawer
  • @nano-ui-kit/web-components/components/embed
  • @nano-ui-kit/web-components/components/empty-state
  • @nano-ui-kit/web-components/components/field
  • @nano-ui-kit/web-components/components/grid
  • @nano-ui-kit/web-components/components/heatmap
  • @nano-ui-kit/web-components/components/icon
  • @nano-ui-kit/web-components/components/image
  • @nano-ui-kit/web-components/components/input
  • @nano-ui-kit/web-components/components/inspector
  • @nano-ui-kit/web-components/components/kbd
  • @nano-ui-kit/web-components/components/list
  • @nano-ui-kit/web-components/components/menu
  • @nano-ui-kit/web-components/components/modal
  • @nano-ui-kit/web-components/components/noodles
  • @nano-ui-kit/web-components/components/option-card
  • @nano-ui-kit/web-components/components/otp-input
  • @nano-ui-kit/web-components/components/pagination
  • @nano-ui-kit/web-components/components/pane
  • @nano-ui-kit/web-components/components/pipeline-status
  • @nano-ui-kit/web-components/components/popover
  • @nano-ui-kit/web-components/components/progress
  • @nano-ui-kit/web-components/components/progress-row
  • @nano-ui-kit/web-components/components/radio
  • @nano-ui-kit/web-components/components/range
  • @nano-ui-kit/web-components/components/rating
  • @nano-ui-kit/web-components/components/richtext
  • @nano-ui-kit/web-components/components/row
  • @nano-ui-kit/web-components/components/search
  • @nano-ui-kit/web-components/components/segment
  • @nano-ui-kit/web-components/components/segmented
  • @nano-ui-kit/web-components/components/select
  • @nano-ui-kit/web-components/components/skeleton
  • @nano-ui-kit/web-components/components/slider
  • @nano-ui-kit/web-components/components/stack
  • @nano-ui-kit/web-components/components/stat
  • @nano-ui-kit/web-components/components/stepper
  • @nano-ui-kit/web-components/components/stream
  • @nano-ui-kit/web-components/components/swiper
  • @nano-ui-kit/web-components/components/switch
  • @nano-ui-kit/web-components/components/table
  • @nano-ui-kit/web-components/components/table-toolbar
  • @nano-ui-kit/web-components/components/tabs
  • @nano-ui-kit/web-components/components/tag
  • @nano-ui-kit/web-components/components/text
  • @nano-ui-kit/web-components/components/textarea
  • @nano-ui-kit/web-components/components/timeline
  • @nano-ui-kit/web-components/components/toast
  • @nano-ui-kit/web-components/components/toggle-group
  • @nano-ui-kit/web-components/components/toolbar
  • @nano-ui-kit/web-components/components/tooltip
  • @nano-ui-kit/web-components/components/tree
  • @nano-ui-kit/web-components/components/upload
  • @nano-ui-kit/web-components/core
  • @nano-ui-kit/web-components/core/anchor
  • @nano-ui-kit/web-components/core/controller
  • @nano-ui-kit/web-components/core/data-stream
  • @nano-ui-kit/web-components/core/data-stream.test
  • @nano-ui-kit/web-components/core/element
  • @nano-ui-kit/web-components/core/element.test
  • @nano-ui-kit/web-components/core/form
  • @nano-ui-kit/web-components/core/icons
  • @nano-ui-kit/web-components/core/icons-manifest
  • @nano-ui-kit/web-components/core/index
  • @nano-ui-kit/web-components/core/markdown
  • @nano-ui-kit/web-components/core/polyfills
  • @nano-ui-kit/web-components/core/provider
  • @nano-ui-kit/web-components/core/signals
  • @nano-ui-kit/web-components/core/streams-bridge
  • @nano-ui-kit/web-components/core/template
  • @nano-ui-kit/web-components/core/transport
  • @nano-ui-kit/web-components/css
  • @nano-ui-kit/web-components/package.json
  • @nano-ui-kit/web-components/patterns
  • @nano-ui-kit/web-components/patterns/a2ui-root
  • @nano-ui-kit/web-components/patterns/app-nav
  • @nano-ui-kit/web-components/patterns/app-nav-group
  • @nano-ui-kit/web-components/patterns/app-nav-item
  • @nano-ui-kit/web-components/patterns/app-shell
  • @nano-ui-kit/web-components/patterns/gen-ui
  • @nano-ui-kit/web-components/patterns/nano-chat
  • @nano-ui-kit/web-components/patterns/nano-editor
  • @nano-ui-kit/web-components/patterns/section-nav
  • @nano-ui-kit/web-components/patterns/section-nav-group
  • @nano-ui-kit/web-components/patterns/section-nav-item
  • @nano-ui-kit/web-components/styles/README.md
  • @nano-ui-kit/web-components/styles/colors/index.css
  • @nano-ui-kit/web-components/styles/colors/parameters.css
  • @nano-ui-kit/web-components/styles/colors/primitives-accent.css
  • @nano-ui-kit/web-components/styles/colors/primitives-brand.css
  • @nano-ui-kit/web-components/styles/colors/primitives-danger.css
  • @nano-ui-kit/web-components/styles/colors/primitives-info.css
  • @nano-ui-kit/web-components/styles/colors/primitives-neutral.css
  • @nano-ui-kit/web-components/styles/colors/primitives-shared.css
  • @nano-ui-kit/web-components/styles/colors/primitives-success.css
  • @nano-ui-kit/web-components/styles/colors/primitives-warning.css
  • @nano-ui-kit/web-components/styles/colors/primitives.css
  • @nano-ui-kit/web-components/styles/colors/scrims.css
  • @nano-ui-kit/web-components/styles/colors/semantics.css
  • @nano-ui-kit/web-components/styles/colors/surfaces.css
  • @nano-ui-kit/web-components/styles/components.css
  • @nano-ui-kit/web-components/styles/editorial.css
  • @nano-ui-kit/web-components/styles/fonts.css
  • @nano-ui-kit/web-components/styles/layouts/admin.css
  • @nano-ui-kit/web-components/styles/prose.css
  • @nano-ui-kit/web-components/styles/resets.css
  • @nano-ui-kit/web-components/styles/themes.css
  • @nano-ui-kit/web-components/styles/tokens.css
  • @nano-ui-kit/web-components/styles/typography.css
  • @nano-ui-kit/web-components/traits
  • @nano-ui-kit/web-components/traits/active-state
  • @nano-ui-kit/web-components/traits/anchor-positioning
  • @nano-ui-kit/web-components/traits/attention-pulse
  • @nano-ui-kit/web-components/traits/confetti
  • @nano-ui-kit/web-components/traits/confetti-burst
  • @nano-ui-kit/web-components/traits/count-up
  • @nano-ui-kit/web-components/traits/define
  • @nano-ui-kit/web-components/traits/dirty-state
  • @nano-ui-kit/web-components/traits/drag-ghost
  • @nano-ui-kit/web-components/traits/draggable
  • @nano-ui-kit/web-components/traits/fade-presence
  • @nano-ui-kit/web-components/traits/focus-trap
  • @nano-ui-kit/web-components/traits/focusable
  • @nano-ui-kit/web-components/traits/glow-focus
  • @nano-ui-kit/web-components/traits/gradient-shift
  • @nano-ui-kit/web-components/traits/haptic-feedback
  • @nano-ui-kit/web-components/traits/hotkey
  • @nano-ui-kit/web-components/traits/hoverable
  • @nano-ui-kit/web-components/traits/index
  • @nano-ui-kit/web-components/traits/inertia-drag
  • @nano-ui-kit/web-components/traits/intersection-observer
  • @nano-ui-kit/web-components/traits/keyboard-nav
  • @nano-ui-kit/web-components/traits/magnetic-hover
  • @nano-ui-kit/web-components/traits/noise-texture
  • @nano-ui-kit/web-components/traits/parallax
  • @nano-ui-kit/web-components/traits/portal
  • @nano-ui-kit/web-components/traits/pressable
  • @nano-ui-kit/web-components/traits/resizable
  • @nano-ui-kit/web-components/traits/resize-observer
  • @nano-ui-kit/web-components/traits/ripple
  • @nano-ui-kit/web-components/traits/roving-tabindex
  • @nano-ui-kit/web-components/traits/scale-press
  • @nano-ui-kit/web-components/traits/scroll-lock
  • @nano-ui-kit/web-components/traits/shimmer-loading
  • @nano-ui-kit/web-components/traits/snap-to-grid
  • @nano-ui-kit/web-components/traits/sound-feedback
  • @nano-ui-kit/web-components/traits/spring-animate
  • @nano-ui-kit/web-components/traits/tilt-hover
  • @nano-ui-kit/web-components/traits/tossable
  • @nano-ui-kit/web-components/traits/typeahead
  • @nano-ui-kit/web-components/traits/typewriter
  • @nano-ui-kit/web-components/traits/validation

Readme

@nano-ui-kit/web-components

Vanilla web components + A2UI runtime for NanoUI. 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 @nano-ui-kit/a2ui-compose; the pattern corpus in @nano-ui-kit/a2ui-corpus; the MCP server in @nano-ui-kit/a2ui-mcp.

Quick start

<link rel="stylesheet" href="node_modules/@nano-ui-kit/web-components/index.css" />

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

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

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       NanoElement — light-DOM reactive base
│   ├── form.js          NanoFormElement — form-associated + validation
│   ├── provider.js      global provider registration + router-n
│   ├── anchor.js        popover + anchor-positioning
│   ├── markdown.js      lightweight markdown renderer
│   └── transport.js     SSE / streaming helpers for LLM adapters
│
├── components/     — 80 *-n custom elements
│   └── <tag>/
│       ├── <tag>.js       class definition (extends NanoElement)
│       ├── <tag>.css      @scope(tag-n) two-block: tokens + styles
│       ├── <tag>.yaml     authoring contract (props, slots, events, examples)
│       └── <tag>.a2ui.json  generated — do NOT edit
│
├── patterns/       — Higher-level compositions (tag: `nano-*`)
│   ├── app-shell, app-nav, section-nav   — admin layout scaffolding
│   ├── nano-chat, nano-editor, gen-ui    — LLM + editor + gen-UI patterns
│   └── index.js                          — registers all patterns
│
├── traits/         — 40 composable behaviors via defineTrait()
│                     (pressable, focusTrap, confetti, resizable, …)
│
└── styles/         — Global tokens and CSS layering
    ├── tokens.css              all --n-* design tokens
    ├── colors/                 primitives / semantics / scrims
    ├── typography.css, space.css, radius.css, shadow.css
    └── themes/*.css            8 themes (ocean, forest, sunset, …)

The A2UI runtime (renderer, registry, wiring engine) lives in @nano-ui-kit/a2ui-utils — installed as a dep; imported from patterns/a2ui-root/a2ui-root.js. LLM transport lives in @nano-ui-kit/gateway — the nano-chat pattern imports the browser adapters from there. Build + training scripts live at the repo root (/scripts), not in this package.

Component contract

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

@scope (button-n) {
  :where(:scope) {
    /* Tokens only — zero specificity, parent overrides win */
    --button-bg:     var(--n-accent-bg);
    --button-fg:     var(--n-accent-fg);
    --button-radius: var(--n-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(--n-danger-bg);   /* variants override tokens, not styles */
  }
}

Authoring rules (enforced by coherence-audit):

  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 nano-ui-author skill encodes the 20 non-negotiable rules.

Card-n / drawer-n 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 '@nano-ui-kit/a2ui-utils';

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-n) so generated output is robust to name drift.

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

gen-ui  ──reads──>  a2ui-corpus  ←─reads──  web-components
a2ui-mcp  ──reads──>  gen-ui, a2ui-corpus

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

License

MIT