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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@affino/menu-vue

v1.0.0-alpha.11

Published

Headless Vue 3 menu components with smart mouse prediction and full keyboard accessibility

Readme

@affino/menu-vue

Vue's most advanced headless menu system — instant accessibility, diagonal mouse prediction, and zero lock-in.

<script setup lang="ts">
import { UiMenu, UiMenuTrigger, UiMenuContent, UiMenuItem } from '@affino/menu-vue'
const actions = ['Edit', 'Duplicate', 'Archive']
</script>

<template>
  <UiMenu>
    <UiMenuTrigger>Actions</UiMenuTrigger>
    <UiMenuContent>
      <UiMenuItem v-for="action in actions" :key="action" @select="() => console.log(action)">
        {{ action }}
      </UiMenuItem>
    </UiMenuContent>
  </UiMenu>
</template>
npm install @affino/menu-vue

Core Features

  • Headless Vue 3 components powered by @affino/menu-core
  • WAI-ARIA compliant keyboard and pointer handling out of the box
  • Smart mouse prediction keeps submenus open during diagonal travel
  • Unlimited submenu depth with shared tree state and focus safety
  • asChild pattern lets you keep native elements and design systems
  • Built-in context menu + click menu support with unified API
  • Auto positioning and viewport collision handling without extra deps
  • Snapshot-driven state subscriptions for zero wasted renders
  • Programmatic controller for imperative open/close/highlight flows
  • CSS variable theme surface for light/dark/brand combos
  • First-class TypeScript types for every prop, event, and controller method
  • Works with virtualization strategies for 1000+ items

Docs → ./docs/index.md

Why this library exists

  • HeadlessUI couples logic to Tailwind-era assumptions, lacks mouse prediction, and breaks under deep submenu trees.
  • Radix Vue mirrors React APIs but still ties you to their opinionated slot structure and no framework-agnostic core.
  • Naive UI ships batteries-included menus, but styling + behavior are inseparable, making custom UX nearly impossible.
  • Designers demanded diagonal hover intent, perf on 1000-row tables, and context menus that feel native — so we built it.

Highlights of architecture

  • Shared observable menu tree keeps open/active paths in sync across levels.
  • Pointer heuristics run outside Vue render cycle for predictable 60fps intent detection.
  • Adapter layer returns ready-to-spread props so DOM stays under your control.
  • Controller API exposes open/close/highlight/select hooks for automation.
  • Positioner computes anchor/panel geometry with gutter + viewport padding inputs.
  • asChild cloning ensures ARIA + event wiring survive custom elements.
  • Core is framework-agnostic, so Menu Vue stays tiny and future-proof.

Feature Comparison Table

| Feature | @affino/menu-vue | |---------|---------------------| | Smart mouse prediction | ✅ | | Unlimited nested submenus | ✅ | | Auto positioning | ✅ | | asChild pattern | ✅ | | Framework-agnostic core | ✅ | | Context + click menus | ✅ | | Programmatic controller | ✅ | | Bundle size (min+gzip) | ~8 KB | | Virtualization ready | ✅ | | TypeScript coverage | 100% |

Getting Started

  1. npm install @affino/menu-vue
  2. Import your global CSS followed by the menu styles in your app entry (usually main.ts) so the design tokens are available everywhere:
import '@affino/menu-vue/styles.css'
  1. Wrap your trigger + content with <UiMenu> / <UiMenuTrigger> / <UiMenuContent>
  2. Spread controller props onto your DOM via asChild when customizing
  3. Add nested <UiSubMenu> components for multi-level trees (level 3+ supported)
  4. Dive deeper in docs/getting-started.md

Live Examples

Try it yourself in under 30 seconds:

FAQ

  • Does it work with Nuxt / SSR? Yes. Components render on the server and hydrate with zero config.
  • Can I disable mouse prediction? Pass :options="{ mousePrediction: null }" on UiMenu.
  • How do I run context menus? Use trigger="contextmenu" or open the controller at pointer coordinates (see guide/context-menu.md).
  • What about huge data sets? Pair <UiMenuContent> with vue-virtual-scroller (recipe in guide/virtualization.md).

Browser Support

  • Evergreen Chromium, Firefox, Safari (ES2020+)
  • Vue 3.4+
  • TypeScript 5+

License

MIT © affino OSS