@aria-ui/elements

中文文档
0.2.0发布于 2026/10/21MITTypeScriptES Module构建来源已验证近 30 天下载 11.1万

Unstyled Light-DOM-Only Web Components

原始使用文档
文档目录12 节
  1. Features
  2. Components
  3. Installation
  4. Quick start
  5. Listbox example
  6. Menu example
  7. Tree-shakable subpath imports
  8. Setting props
  9. Styling
  10. Events
  11. Using with frameworks
  12. License

@aria-ui/elements

A set of unstyled, accessible Light-DOM-Only Web Components for building user interfaces. Inspired by Radix UI and Ark UI, but shipped as native custom elements that work in any framework — or in plain HTML.

Playground: https://aria-ui.pages.dev/

Features

  • Light DOM only. No Shadow DOM, so your global stylesheet, Tailwind classes, and selectors like [aria-selected="true"] or [data-active] apply directly to the elements you put on the page.
  • Unstyled by design. Every component ships zero CSS. State is exposed via standard ARIA attributes and data-* attributes for you to style however you like.
  • Built on the WAI-ARIA APG. Keyboard interactions, focus management, and ARIA roles follow the WAI-ARIA Authoring Practices Guide patterns.
  • Composable parts. Each component is split into focused custom elements (*-root, *-trigger, *-popup, *-positioner, *-item, …) that communicate through a shared store.
  • Framework-agnostic. Use the elements directly in HTML, or generate framework wrappers with @aria-ui/cli for React, Vue, Solid, Preact, and Svelte.

Components

ComponentCustom elements
Listboxaria-ui-listbox-root, aria-ui-listbox-item, aria-ui-listbox-empty
Menuaria-ui-menu-root, aria-ui-menu-trigger, aria-ui-menu-positioner, aria-ui-menu-popup, aria-ui-menu-item, aria-ui-menu-submenu-root, aria-ui-menu-submenu-trigger
Popoveraria-ui-popover-root, aria-ui-popover-trigger, aria-ui-popover-positioner, aria-ui-popover-popup
Tooltiparia-ui-tooltip-root, aria-ui-tooltip-trigger, aria-ui-tooltip-positioner, aria-ui-tooltip-popup

Installation

npm install @aria-ui/elements
# or
pnpm add @aria-ui/elements

Quick start

Register every component with a single call:

import { registerElements } from '@aria-ui/elements'

registerElements()

Then use the elements anywhere in your HTML:

<aria-ui-popover-root>
  <aria-ui-popover-trigger tabindex="0">Open popover</aria-ui-popover-trigger>
  <aria-ui-popover-positioner>
    <aria-ui-popover-popup>
      <p>Hello from a popover!</p>
    </aria-ui-popover-popup>
  </aria-ui-popover-positioner>
</aria-ui-popover-root>

Listbox example

<aria-ui-listbox-root>
  <aria-ui-listbox-item value="apple">Apple</aria-ui-listbox-item>
  <aria-ui-listbox-item value="banana">Banana</aria-ui-listbox-item>
  <aria-ui-listbox-item value="cherry">Cherry</aria-ui-listbox-item>
</aria-ui-listbox-root>
const listbox = document.querySelector('aria-ui-listbox-root')!
listbox.addEventListener('valueChange', (event) => {
  console.log('Selected:', event.detail)
})

Menu example

<aria-ui-menu-root>
  <aria-ui-menu-trigger tabindex="0">Actions</aria-ui-menu-trigger>
  <aria-ui-menu-positioner>
    <aria-ui-menu-popup>
      <aria-ui-menu-item value="cut">Cut</aria-ui-menu-item>
      <aria-ui-menu-item value="copy">Copy</aria-ui-menu-item>
      <aria-ui-menu-item value="paste">Paste</aria-ui-menu-item>
    </aria-ui-menu-popup>
  </aria-ui-menu-positioner>
</aria-ui-menu-root>

Tree-shakable subpath imports

Each component is also published under its own subpath, so you can register only the parts you need:

import { registerListboxRootElement, registerListboxItemElement } from '@aria-ui/elements/listbox'

registerListboxRootElement()
registerListboxItemElement()

Available entry points:

  • @aria-ui/elements — full bundle plus registerElements()
  • @aria-ui/elements/listbox
  • @aria-ui/elements/menu
  • @aria-ui/elements/popover
  • @aria-ui/elements/tooltip
  • @aria-ui/elements/overlay — shared overlay primitives

Setting props

Every prop is available as both an HTML attribute and a JS property. Complex values (arrays, objects, null) are stored as JSON:

<!-- Via attributes -->
<aria-ui-listbox-root multiple values='["apple","banana"]'>
  <aria-ui-listbox-item value="apple">Apple</aria-ui-listbox-item>
  <aria-ui-listbox-item value="banana">Banana</aria-ui-listbox-item>
</aria-ui-listbox-root>
// Via JS properties
const listbox = document.querySelector('aria-ui-listbox-root')!
listbox.multiple = true
listbox.values = ['apple', 'banana']

Styling

Components expose their state through standard accessibility attributes and a few data-* attributes:

AttributeUsed byMeaning
aria-selected="true"listbox itemsThe option is selected
aria-expanded="true"popover/menu/tooltip triggersThe overlay is open
aria-disabled="true"any elementThe element is disabled
data-activelistbox items, menu itemsThe element is the currently highlighted option (aria-activedescendant)
data-state="open" | "closed"overlay popupsOverlay open state, useful for transitions

Example with Tailwind:

<aria-ui-listbox-item
  value="apple"
  class="block px-3 py-2 cursor-pointer hover:bg-blue-50 aria-selected:bg-blue-100 data-active:outline-2 data-active:outline-blue-500"
>
  Apple
</aria-ui-listbox-item>

Events

Components dispatch standard DOM events whose payload lives on the detail property:

EventDispatched bydetail
valueChangelistbox (single select)string
valuesChangelistbox (multi-select)string[]
openChangepopover, menu, tooltipboolean
selectmenu item, listbox item(no payload)

valueChange / valuesChange are cancelable — call event.preventDefault() to take over the state yourself and run the listbox in a controlled mode.

Using with frameworks

For React, Vue, Solid, Preact, and Svelte you can generate typed wrapper components with @aria-ui/cli, which handles attribute/property mapping and converts DOM events into idiomatic framework callbacks.

License

MIT

版本与发布记录

@aria-ui/elements 共发布 28 个版本,首次发布于 2026/03/29;过去 12 个月发布了 28 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.2.0latest2026/10/2117 天前
0.1.142026/10/2117 天前
0.1.132026/08/122 个月前
0.1.122026/07/044 个月前
0.1.112026/06/304 个月前
0.1.102026/05/155 个月前

关于 @aria-ui/elements 的常见问题

@aria-ui/elements 是什么?

Unstyled Light-DOM-Only Web Components

如何安装 @aria-ui/elements?

在项目目录运行 npm install @aria-ui/elements,或使用 pnpm add / yarn add / bun add。

@aria-ui/elements 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@aria-ui/elements 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@aria-ui/elements 可以商用吗?

@aria-ui/elements 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@aria-ui/elements 的下载量有多少?

根据 npm 官方下载统计,@aria-ui/elements 在 2026/10/07 – 2026/11/05 这 30 天内被下载 111,301 次,日均约 3,710 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@aria-ui/elements 还在维护吗?

最新版本 0.2.0 发布于 2026/10/21(17 天前);至今共发布 28 个版本,其中过去 12 个月发布了 28 个;首次发布于 2026/03/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。