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

@proj-airi/ui

v0.15.2

Published

A collection of UI components that used by Project AIRI

Readme

@proj-airi/ui

A stylized UI component library built with Reka UI and UnoCSS.

To preview the components, refer to the stage-ui package for instructions for running the Histoire UI storyboard.

Get started

Install the library:

ni @proj-airi/ui -D # from @antfu/ni, can be installed via `npm i -g @antfu/ni`
pnpm i @proj-airi/ui -D
yarn i @proj-airi/ui -D
npm i @proj-airi/ui -D

This library requires unocss with Attributify Mode and a style reset.

First, install unocss if you haven't already:

pnpm i -D unocss

Next, in your uno.config.ts, add presetAttributify() to your presets array:

import { defineConfig, presetAttributify } from 'unocss'

export default defineConfig({
  presets: [
    presetAttributify(),
    // ...your other presets
  ],
})

Finally, import the reset styles in your main.ts:

import '@unocss/reset/tailwind.css'

Usage

<script setup lang="ts">
import { Button } from '@proj-airi/ui'
</script>

<template>
  <Button>Click me</Button>
</template>

Components

License

MIT

Swipe actions

Compose SwipeActionsRoot, SwipeActionsContent, SwipeActionsList, and SwipeActionsItem. Bind v-model:open on Root and give each Item a unique, stable value within its List. Add Lists with side="start" and side="end" for bidirectional swipes. Root's v-model:side selects the revealed edge; dir maps logical edges in RTL. Its action(value, side) event identifies the selected action. Each List uses its last Item as the long-swipe default. The List's defaultAction can choose a different value; fullSwipe=false disables long-swipe selection.

Items register and follow DOM order automatically. Reordering or removing them cancels pending gestures. All parts support Reka UI's as and asChild. List controls per-action width and gap. :gap="16" leaves 16px between Items and 8px at each outer edge, including beside Content during entry. Its container size lets Items appear one at a time from the outer edge, with reversible scale and opacity curves. Items without space remain registered but cannot receive input or focus. Use an opaque background for Content.

Use SwipeActionButton inside SwipeActionsItem as-child for the standard surface, icon, and text. Pass the Item slot's takeover and physical edge to the button. showLabel=false fills the former text area while keeping the accessible name.

Use these components for persistent action areas on either side. They do not own conversation storage, undo, or swipe-to-reply behavior. See the component reference and the stage-ui Histoire story Misc → Swipe Actions.