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

@designesy/focal

v0.1.1

Published

Keyboard focus, carried by real light: a solid outline chosen by measured contrast, and with Sill, the page's lamp travels to focus and the focused control lifts toward it. Zero dependencies.

Readme

Focal

Keyboard focus, carried by real light.

Live demos · press Tab.

The focused control gets a real outline whose colour is chosen by measuring contrast against the surface it sits on. With Sill on the page, the page's own lamp travels to whatever has focus and the control lifts toward it: its shadow lengthens, its edges catch the light, and the shadows across the page swing as the lamp moves, so the eye follows a jump. Nothing is drawn on top. No glow, no halo: the emphasis is the light itself, so keyboard users get the same physical interface pointer users do.

npm install @designesy/focal
import '@designesy/focal/focal.css';
import { Focal } from '@designesy/focal';

new Focal();              // on its own: the measured outline and the obscured-focus fix
new Focal({ sill });      // with Sill: the lamp travels to focus and the control lifts

No build step:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@designesy/[email protected]/src/focal.css">
<script type="module">
  import { Focal } from 'https://cdn.jsdelivr.net/npm/@designesy/[email protected]/src/focal.js';
  new Focal();
</script>

The light comes from Sill (@designesy/sill). Without it, Focal is still a complete focus indicator; it simply has no lamp to move.

What it guarantees

  • A real outline, always. The light is added on top of a solid outline and can be removed without losing the indicator. The default 2 px outline at a 3 px offset meets the area floor of WCAG 2.2 SC 2.4.13 Focus Appearance for any component size (tested).
  • 3:1 where it counts. SC 2.4.13 measures the indicator's own pixels between the focused and unfocused states. Drawn outside the element, those pixels sit on the parent's background, so Focal picks the ring colour that keeps at least 3:1 there. Among colours that pass, it prefers your first choice when that also reads at 3:1 against the element itself. On a blue button on white, that switches the ring away from blue automatically.
  • Focus is never hidden behind sticky content. After every move, Focal checks whether author content such as a sticky header covers the focused element (SC 2.4.11 Focus Not Obscured, and 2.4.12 for partial cover), warns in the console, and scrolls it clear.
  • Reduced motion means no travel. Under prefers-reduced-motion, the lamp is placed at the new focus without sweeping there.
  • Forced colours means the system's colours. In Windows High Contrast and other forced-colour modes, the outline uses Highlight and the lamp does not travel.
  • It changes nothing about focus. Focal never moves focus, never changes tab order, and draws nothing that can be clicked. It only shows where focus already is.

Options

| Option | Default | Controls | |---|---|---| | sill | null | a Sill instance to lift toward and steer | | ringWidth | 2 | outline width in px | | ringOffset | 3 | outline offset in px | | ringColors | ['#0a94ff', '#016abb', '#ffffff', '#1a1a1e'] | ring colours, in order of preference | | lift | 12 | extra elevation for a focused lit element (Sill) | | followLight | true | the light follows keyboard focus (Sill) | | sweep | true | the lamp travels to the new focus instead of jumping (Sill) | | lightOffset | [-60, -120] | where the lamp sits relative to the control's centre, px (Sill) | | fixObscured | true | scroll focus clear of covering content | | warnObscured | true | console warning when focus is covered |

Visually hidden native inputs (a custom switch or segmented control) can name the part people see, so the ring and the light land there:

<label class="switch">
  <input type="checkbox" role="switch" data-focal-target=".switch-track">
  <span class="switch-track"></span>
</label>

Call focal.refresh() after a theme change so the ring is measured against the new surfaces.

Events: focal:move (detail.from, detail.to) and focal:obscured (detail.fraction, detail.entirely, detail.cover) bubble from the focused element.

Demos

Live at le-vai.github.io/focal.

  • demo/settings/ is a settings page with a sticky header, a skip link, a theme control that really switches between light and dark, and controls spread across the page. Press Tab.
  • demo/end/ is the wordmark, lit by Sill and focused by Focal.

To run them locally:

python -m http.server 4742

Then open http://localhost:4742/demo/settings/.

Browser support

Focal needs nothing beyond :focus-visible and requestAnimationFrame. Tested in Chrome 154 and Firefox 152 on Windows: focus travel, eased lift, theme switching and ring re-measurement, with no console errors. Safari is not yet tested.

License

MIT © 2026 LE-VAI. Part of the Designesy stack.