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

vue-key-mgr

v0.1.2

Published

A context-aware, reactive key-management system for Vue 3.

Downloads

61

Readme

vue-key-mgr

A context-aware, reactive key-management system for Vue 3.

Features

  • Hierarchical Schema: Define keys in categories with nested enabled states.
  • Reactive: Key availability is driven by Vue's reactive state (Refs/Computeds).
  • Declarative: No manual stack management; the schema state drives the key map.
  • Path-based Subscriptions: Subscribe to specific actions or entire categories.
  • Automatic Prevention: Handles event.preventDefault() automatically (configurable).
  • Ignore List: Automatically ignores events from inputs, textareas, or custom selectors.
  • Serialization: Easily export and hydrate key bindings for user-defined shortcuts.
  • Active Key Tracking: Reactive list of currently available keys for UI/Status bars.
  • Custom Input Providers: Support for gamepads, MIDI, or any HID device via a simple provider API.
  • Universal Input Mode: Single action can be bound to multiple keyboard, gamepad, and custom inputs.

Installation

...

Serialization & Persistence

You can export the current key configuration (minus the reactive logic) to save to a database or localStorage:

const { getBindings, applyBindings } = useKeyManager()

// Save
const bindings = getBindings()
localStorage.setItem('my-keys', JSON.stringify(bindings))

// Load
const saved = localStorage.getItem('my-keys')
if (saved) applyBindings(JSON.parse(saved))

Custom Input Providers

You can register custom systems to trigger actions:

const { registerProvider } = useKeyManager()

registerProvider('gamepad', (emit) => {
  const buttonStates = new Map()

  const poll = () => {
    const gps = navigator.getGamepads()
    for (const gp of gps) {
      if (!gp) continue
      gp.buttons.forEach((btn, i) => {
        const wasPressed = buttonStates.get(`${gp.index}_${i}`)
        if (btn.pressed && !wasPressed) {
          emit(`button_${i}`, { gamepad: gp })
        }
        buttonStates.set(`${gp.index}_${i}`, btn.pressed)
      })
    }
    requestAnimationFrame(poll)
  }
  requestAnimationFrame(poll)
})

Then in your schema:

{
  name: 'jump',
  inputs: [
    { key: 'space' }, // default type: keyboard
    { type: 'gamepad', slug: 'button_0' }
  ]
}

Active Key Tracking (Status Bar)

To show which keys are currently active in the UI:

const { activeKeys } = useKeyManager()

activeKeys is a shallowRef containing an array of objects: { action: Object, path: string, categoryPath: string, combo: string }

<div class="status-bar">
  <span v-for="key in activeKeys" :key="key.path">
    {{ key.combo }}: {{ key.action.desc }}
  </span>
</div>

Schema Structure

npm install vue-key-mgr


## Quick Start

### 1. Define your Schema and Initialize

In your main entry point or a top-level component:

```javascript
import { useKeyManager } from 'vue-key-mgr'
import { ref, computed } from 'vue'

const isEditorActive = ref(true)

const schema = {
  categories: [
    {
      name: 'editor',
      enabled: isEditorActive,
      actions: [
        { name: 'save', key: 's', modifiers: ['ctrl'], desc: 'Save' }
      ]
    }
  ]
}

const { initKeyMgr } = useKeyManager()
initKeyMgr(schema)

2. Subscribe to Actions

In any component:

import { useKeyAction } from 'vue-key-mgr'

useKeyAction('editor.save', (event, action) => {
  console.log('Saving project...')
})

3. Category Listeners & Propagation

You can also listen to entire categories and stop propagation to parent listeners:

useKeyAction('editor', (event, action, { stopPropagation }) => {
  console.log(`Any action in 'editor' triggered: ${action.name}`)
  // stopPropagation() // Prevent bubbling to higher categories
})

Schema Structure

  • Category:
    • name: string (used in path)
    • enabled: Ref | ComputedRef | boolean
    • actions: Array of Action objects
    • categories: Nested Categories
  • Action:
    • name: string (used in path)
    • key: string (e.g., 'f1', 'e', 'enter') - Legacy single key mode
    • modifiers: Array of strings ('ctrl', 'alt', 'shift', 'meta') - Legacy single key mode
    • keys: Array of { key: string, modifiers?: string[] } - Multi-key keyboard mode
    • inputs: Array of { type?: string, key?: string, modifiers?: string[], slug?: string } - Universal input mode
    • allowDefault: boolean (default: false)
    • desc: string (optional description)

Development

# Start dev environment (demo app)
npm run dev

# Build library
npm run build