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

@upgraide/ui-notes-react

v0.2.7

Published

React components for UI Notes - capture and display UI feedback annotations

Readme

@upgraide/ui-notes-react

Drop-in React component that adds visual feedback annotations to any page.

Installation

npm install -D @upgraide/ui-notes-react

This is a development/QA tool — install it as a dev dependency so it doesn't ship in your production bundle.

Peer dependencies: React 18 or 19

Quick Start

import { UINotes } from "@upgraide/ui-notes-react";

function App() {
  return (
    <>
      <YourApp />
      <UINotes
        apiUrl="https://your-api.example.com"
        apiKey="your-api-key"
        project="my-app"
      />
    </>
  );
}

That's it. A floating button appears in the bottom-right corner. Click it to open the notes panel or start annotating elements on the page.

Production: See Disabling in Production to make sure the component is fully excluded from production builds.

How It Works

  1. Toggle — Click the floating button to open the panel
  2. Annotate — Click "Start Annotating", hover over elements to highlight them, click one to open the note form
  3. Submit — Pick a type (Bug, UX Issue, Feature Request, or Question), write a description, and submit
  4. View — Colored markers appear on annotated elements. Click them to see details, or browse all notes in the panel

Props

| Prop | Type | Description | |------|------|-------------| | apiUrl | string | Base URL of your UI Notes API server | | apiKey | string | API key for authentication | | project | string | Project slug to scope notes to |

Note Types

| Type | Color | |------|-------| | Bug | Red | | UX Issue | Orange | | Feature Request | Blue | | Question | Purple |

Keyboard Shortcuts

| Key | Action | |-----|--------| | Ctrl+Shift+A / Cmd+Shift+A | Toggle annotation mode on/off | | Ctrl+Shift+Z / Cmd+Shift+Z | Toggle show notes on page | | Escape | Close form or tooltip | | Ctrl+Enter / Cmd+Enter | Submit note |

Element Detection

When you annotate an element, the component automatically captures:

  • Component name — from data-component or data-testid attributes
  • CSS selector — prefers data-testid, then id, then tag+class combinations
  • Text content — first 100 characters of the element's text
  • URL — current page URL
  • HTML tag — the element's tag name

Add data-component or data-testid attributes to your elements for better annotation labels.

Exports

Components

  • UINotes — Main component (default). Renders the widget and annotation layer.

API Client

import { UINotesAPI } from "@upgraide/ui-notes-react";

const api = new UINotesAPI("https://api.example.com", "your-key", "my-project");
const notes = await api.getNotes("open");
await api.createNote({ type: "bug", body: "Button is broken", ...elementData });

Types

import type { Note, CapturedElement, UINoteProps } from "@upgraide/ui-notes-react";
  • Note — Full note object with id, type, body, status, selector, component, etc.
  • CapturedElement — Data captured from an annotated DOM element
  • UINoteProps — Props for the UINotes component

Utilities

import { captureElement, detectComponent, generateSelector, timeAgo } from "@upgraide/ui-notes-react";
  • captureElement(el) — Extract metadata from a DOM element
  • detectComponent(el) — Find component name from data attributes
  • generateSelector(el) — Create a CSS selector for an element
  • timeAgo(dateStr) — Format a date string as relative time (e.g. "2 hours ago")

Styling

All styles are self-contained — no CSS imports needed. The component uses inline styles and renders via React portals to avoid layout interference with your app.

Disabling in Production

Since this is a dev/QA tool, you'll want to exclude it from production builds entirely. There are a few approaches:

Environment variable check

{process.env.NODE_ENV !== "production" && (
  <UINotes apiUrl="..." apiKey="..." project="..." />
)}

Most bundlers (Vite, webpack, Next.js) will tree-shake the component out of production builds when using process.env.NODE_ENV.

Feature flag

Use a dedicated env variable for more control (e.g. enable in staging but not production):

{process.env.NEXT_PUBLIC_UINOTES_ENABLED === "true" && (
  <UINotes apiUrl="..." apiKey="..." project="..." />
)}

Dynamic import

To avoid loading the module at all in production:

import { lazy, Suspense } from "react";

const UINotes = lazy(() => import("@upgraide/ui-notes-react"));

function App() {
  return (
    <>
      <YourApp />
      {process.env.NODE_ENV !== "production" && (
        <Suspense fallback={null}>
          <UINotes apiUrl="..." apiKey="..." project="..." />
        </Suspense>
      )}
    </>
  );
}

Framework Notes

Next.js

Environment variables used in client-side code must be prefixed with NEXT_PUBLIC_:

NEXT_PUBLIC_UINOTES_API_URL=https://your-api.example.com
NEXT_PUBLIC_UINOTES_API_KEY=your-api-key
NEXT_PUBLIC_UINOTES_ENABLED=true
{process.env.NEXT_PUBLIC_UINOTES_ENABLED === "true" && (
  <UINotes
    apiUrl={process.env.NEXT_PUBLIC_UINOTES_API_URL}
    apiKey={process.env.NEXT_PUBLIC_UINOTES_API_KEY}
    project="my-app"
  />
)}

The component must be used in a Client Component (add "use client" at the top of the file).

Vite

Vite exposes env variables prefixed with VITE_:

VITE_UINOTES_API_URL=https://your-api.example.com
VITE_UINOTES_API_KEY=your-api-key
<UINotes
  apiUrl={import.meta.env.VITE_UINOTES_API_URL}
  apiKey={import.meta.env.VITE_UINOTES_API_KEY}
  project="my-app"
/>

Build from Source

cd packages/react
bun install
bun run build

Output goes to dist/ — ES module + CommonJS + TypeScript declarations.

License

MIT