Skip to content

A lightweight library that leverages native Web APIs to manage focus navigation based on keyboard arrow key input.

License

Notifications You must be signed in to change notification settings

sunio00000/focus-arrow

Repository files navigation

focus-arrow

A lightweight utility that wires global arrow-key listeners to move focus between tabindex-managed DOM elements based on their visual positions.

✨ Features

  • Visual-position navigation (not DOM order)
  • tabindex-based focusable detection with custom filters
  • Global keydown handling plus user-provided side listeners
  • Framework-agnostic TypeScript build (ESM + CJS) with generated types
  • Ready-to-use Vitest + jsdom environment for development

📦 Installation

npm install focus-arrow

🚀 Quick start

import { FocusArrow } from 'focus-arrow';

const manager = new FocusArrow({
  scope: document.querySelector('[data-focus-scope]') as HTMLElement,
  onNavigate: ({ from, to, direction }) => {
    console.info(`${from?.id ?? 'nothing'} -> ${to?.id ?? 'nothing'} via ${direction}`);
  }
});

// Add extra listeners if needed
const removeListener = manager.addKeydownListener((event) => {
  if (event.key === 'ArrowRight') {
    console.debug('Custom hook!', event);
  }
});

// Later…
removeListener();
manager.destroy();

Options

Option Type Default Description
scope Document | HTMLElement document Element tree used to look up focusable nodes
eventTarget Document | HTMLElement document Target that listens for keydown events
shouldWrap boolean true Wrap to the first/last element if needed
filter (el: HTMLElement) => boolean Custom predicate to include/exclude nodes
onNavigate ({ from, to, direction, event }) => void Callback fired after every navigation try

Focusable elements are detected strictly through the tabIndex >= 0 rule.

🧪 Development & testing

Script Purpose
npm run dev Watch mode for Vitest (ideal while iterating)
npm run test Single-run Vitest suite using jsdom
npm run typecheck TypeScript type-checking without emit
npm run build Bundle with tsup (outputs ESM, CJS, and d.ts)

Vitest is already configured with a jsdom environment. See tests/focusArrow.test.ts for examples that stub getBoundingClientRect to simulate different visual layouts.

About

A lightweight library that leverages native Web APIs to manage focus navigation based on keyboard arrow key input.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published