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

@geastack-community/a11y

v1.0.1

Published

The definitive, Zero-Hooks a11y library for Gea.

Readme

@geastack-community/a11y

The definitive, Zero-Hooks accessibility (a11y) and focus-management library for Gea (@geajs/core).

Designed from the ground up to respect Gea's core philosophy: No Hooks, pure Object-Oriented Programming (OOP), and explicit resource management.

Features

  • 📦 Zero Hooks, 100% Gea-Idiomatic: Built using pure JS Classes and Component Mixins. No implicit reactive magic.
  • ⌨️ Robust Focus Trapping: Locks keyboard focus within modals, dialogs, or drawers, supporting Tab and Shift+Tab looping and blocking focus escape.
  • 🥞 Multi-Modal Nesting Support: Manages a global focus stack (trapStack) seamlessly. Opening multiple nested dialogs or drawers won't break focus restoration or trapping.
  • 🔊 Framework-Agnostic Screen Reader Announcements: Dynamically injects and manages aria-live regions to reliably broadcast updates to screen readers.
  • 🚪 Escape Key Handling: Optional built-in onEscape callback for clean dismissal.
  • 🧹 Auto-Cleanup: Automatically tears down global event listeners, resets state, and restores focus to the previously active element upon component disposal.

Installation

pnpm add @geastack-community/a11y

Quick Start

Wrap your Gea component with the withA11y mixin. Use this.createA11y to instantiate accessibility controllers that tie their lifecycles automatically to the component's dispose().

import { Component } from '@geajs/core';
import { withA11y } from '@geastack-community/a11y';

export default class ModalDialog extends withA11y(Component) {
  private a11y!: any;

  created() {
    // 💡 Creates an a11y instance. Automatically cleaned up when the component is disposed.
    this.a11y = this.createA11y({
      trapFocus: true,
      autoFocus: true,
      restoreFocus: true,
      onEscape: () => this.closeModal()
    });
  }

  mounted() {
    const modalElement = this.el.querySelector('.modal-root') as HTMLElement;
    if (modalElement) {
      this.a11y.init(modalElement);
    }
  }

  private closeModal() {
    this.a11y.announce('Modal closed', 'polite');
    // Close logic here...
  }

  template() {
    return `
      <div class="modal-root" role="dialog" aria-modal="true">
        <h2>Accessible Dialog</h2>
        <p>Focus is safely trapped inside this modal.</p>
        <button onclick="${() => this.closeModal()}">Close</button>
      </div>
    `;
  }
}

API Reference

withA11y(BaseComponent)

A class mixin that extends your Gea Component. It injects the createA11y method and overrides dispose() to clean up all tracked accessibility instances under the hood.

this.createA11y(options)

Returns an instance of GeaA11y that extends Gea's native Store.

Options

| Property | Type | Default | Description | | --- | --- | --- | --- | | trapFocus | boolean | false | Automatically activate the focus trap when init() is called. | | autoFocus | boolean | true | Automatically focuses the first focusable element inside the root element when activated. | | restoreFocus | boolean | true | Restores focus to the previously active element when the trap is deactivated. | | onEscape | (e: KeyboardEvent) => void | undefined | Callback triggered when the Escape key is pressed while the trap is active. |

Methods

  • init(element: HTMLElement): void Binds the accessibility manager to the container element and initializes the trap if configured.
  • activateTrap(): void Manually activates the focus trap and event listeners.
  • deactivateTrap(): void Deactivates the focus trap, removes listeners, and restores previous focus.
  • announce(message: string, politeness?: 'polite' | 'assertive'): void Dispatches a screen reader announcement via a dynamically managed aria-live region.
  • destroy(): void Cleans up all listeners and resets internal states.

Global Utilities

  • _clearA11yGlobalState(): void Forces the cleanup of all active traps in the stack and purges any dynamic aria-live elements from the DOM. Extremely useful in testing environments (e.g., Vitest afterEach).

License

MIT © KoHaRxnP