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

@linkrunner/relay-ui

v0.1.0

Published

Shared Linkrunner React interface primitives.

Readme

@linkrunner/relay-ui

Shared React primitives extracted from the current Linkrunner dashboard. This first package preserves ordinary dashboard button behavior, dimensions, and visual styles, with an explicit Slot adapter for composed links. It contains Button, IconButton, Input, Label, FormFieldLabel, the Tooltip family, the Modal family, and AlertDialog.

Use in an application

Install matching token and UI package versions, then load both stylesheets once in the application's global entry:

import '@linkrunner/relay-tokens/themes.css';
import '@linkrunner/relay-ui/styles.css';

import { Button, Input, TooltipProvider } from '@linkrunner/relay-ui';

export function CampaignForm() {
  return (
    <TooltipProvider>
      <form>
        <Input label="Campaign name" name="campaignName" />
        <Button type="submit" variant="primary">Save campaign</Button>
      </form>
    </TooltipProvider>
  );
}

Keep a single TooltipProvider at the application root in production. Per-component exports are available, for example @linkrunner/relay-ui/button, @linkrunner/relay-ui/modal, and @linkrunner/relay-ui/tooltip. Every JavaScript entry preserves its use client directive for Next.js App Router consumers; React and React DOM remain peer dependencies and are never bundled.

Use class="dark" or data-relay-theme="dark" on the HTML element to switch the entire application, including portaled dialogs and tooltips. Set light mode with data-relay-theme="light" and remove the dark class. A theme applied only to a nested section cannot automatically reach a portal attached to document.body.

Load the application's Inter font asset. The package ships typography values and the dashboard's font feature settings; it does not download fonts or change the host document's font settings.

Link composition

Button asChild accepts one element that forwards DOM props and its ref, such as an anchor or application routing Link. Button styles and handlers reach that element; leftIcon and rightIcon stay package-owned and are composed around its content. The same contract applies to a hybrid button's main action; its second action remains a separate button. A Fragment cannot be used as the child.

<Button asChild leftIcon={<DownloadSimple aria-hidden="true" />}>
  <a href="/reports">Download report</a>
</Button>

While disabled or loading, the child has aria-disabled and tabIndex=-1, activation events are blocked, and native anchors lose their href. Routing components retain their required href and must forward the supplied capture handlers. Loading shows the package spinner while keeping the original child content available as its accessible name. Ordinary buttons keep the dashboard's existing loading behavior.

Styling boundary

The distributed CSS is already compiled. Consumers need neither Tailwind nor a Tailwind content scan. Internal utility classes, animation names, and Tailwind custom properties have a relay- namespace. Component defaults apply only to package-owned elements, including portaled surfaces. There is no document-wide reset.

Consumer className values retain their spelling and can supply layout such as width or margins. They merge with package utilities using the dashboard's current class-composition rules; the winning package classes stay prefixed, and winning application classes use the host stylesheet. Use the existing variants and sizes for appearance. When composing buttonVariants() on a native element, use mergeClasses from @linkrunner/relay-ui/utils; the returned relay-control marker supplies the same scoped CSS defaults as the component.

Tokens are a required peer dependency. The importing application explicitly chooses its token version and loads its theme stylesheet. No package import mutates browser storage, routing, authentication, or data.

Authoritative source

provenance.json records source and packaged SHA-256 hashes for dashboard commit e3e79de0e0ab7b021b7a648b947da3b1c2fe0945. scripts/extract-dashboard.mjs enumerates the mechanical transforms and can verify a checkout:

node scripts/extract-dashboard.mjs --source /path/to/linkrunner-dashboard --ref e3e79de --check

The transforms add client boundaries, replace imports, namespace existing utilities and variables, give four arbitrary CSS properties equivalent named utilities, and mark owned elements for scoped CSS defaults. The recorded Button adapter also adds relay-control to exported variants, fixes direct-child Slot composition, and implements disabled/busy link semantics. --ref reads the original files using git show, so verification still works after the dashboard adopts Relay. --only button can regenerate that component and provenance without writing the other component sources; --check always verifies the full set.

Inherited behavior remains visible: tooltips suppress keyboard focus opening; ordinary loading buttons replace their label with the spinner's accessible label; optional input helper text is not automatically associated by aria-describedby. The existing palette and contrast limitations also remain unchanged. The Slot correction is limited to composed controls and is recorded separately from the mechanical extraction.

Validation

npm run build
npm test

The build emits ESM, TypeScript declarations, and one stylesheet; it checks CSS variable resolution against the token package, scoped Tailwind defaults, selector isolation, theme selection, and every public entry's client boundary. Interaction tests cover loading, split actions, native prop/ref forwarding, input clear behavior, hover tooltips, modal dismissal, and consequential-confirmation behavior. Real consumer builds and browser rendering are validated from packed artifacts by the repository's consumer pilot workflow.