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

@taskp3/react

v0.1.1

Published

TaskP3 React components — drop-in triage button, changelog, and hooks

Downloads

261

Readme

@taskp3/react

React components for TaskP3 — shared triage, changelog, and "What's New" UI for integrations built on the SDK.

For the server-side SDK, see @taskp3/sdk.

Installation

npm install @taskp3/react @taskp3/sdk

Peer dependencies: react >= 17, react-dom >= 17, @taskp3/sdk >= 0.1.0.

Quick Start

  1. Mount the Express adapter on your server (see @taskp3/sdk docs).
  2. Wrap your app with <TaskP3Provider> and mount the shared components:
import { TaskP3Provider, TriageButton, WhatsNew } from "@taskp3/react";

function App() {
  return (
    <TaskP3Provider apiUrl="https://your-app.com/api/triage">
      <YourApp />
      <TriageButton />
      <WhatsNew />
    </TaskP3Provider>
  );
}

Components

<TaskP3Provider>

Required wrapper that configures the API URL, theme, and optional auth headers.

<TaskP3Provider
  apiUrl="https://your-app.com/api/triage"
  theme={{ primaryColor: "#6366f1" }}
  getHeaders={() => ({ Authorization: `Bearer ${token}` })}
>
  {children}
</TaskP3Provider>

| Prop | Type | Required | Description | |---|---|---|---| | apiUrl | string | Yes | Full URL where createTriageRouter is mounted | | theme | TaskP3Theme | No | Visual customisation (see Theming) | | getHeaders | () => Record<string, string> | No | Extra headers sent with every request (e.g. Authorization) | | fetcher | (url: string, init: RequestInit) => Promise<Response> | No | Custom fetch implementation — use to plug in your own API service with interceptors, retry logic, etc. Defaults to native fetch. |

<TriageButton>

Floating help button for the initial triage submission flow: category tabs, file upload, screen recording, and submission.

<TriageButton
  position="bottom-right"
  buttonText="Help"
  onSubmitSuccess={(data) => console.log("Submitted", data)}
/>

| Prop | Type | Default | Description | |---|---|---|---| | position | "bottom-right" \| "bottom-left" | "bottom-right" | Screen corner | | categories | (TriageSubmissionType \| string)[] | All types | Submission types to show | | buttonText | string | "Help" | Button label | | enableFileUpload | boolean | true | Allow file attachments | | onSubmitSuccess | (data: unknown) => void | — | Callback after successful submit | | onSubmitError | (error: Error) => void | — | Callback on error |

TriageButton is the closest CP9 parity surface today. It covers the initial submission happy path well, but full CP9 drop-in behavior still depends on host integration for route state, alerts, and some recorder handoff workflows.

<PastSubmissions>

Shared modal for browsing past submissions: list pane, filters/search/sort, response thread, and a lightweight reply composer.

<PastSubmissions open={open} onClose={() => setOpen(false)} />

| Prop | Type | Required | Description | |---|---|---|---| | open | boolean | Yes | Controls modal visibility | | onClose | () => void | Yes | Close handler | | title | string | No | Modal title | | pageSize | number | No | Page size for submissions/responses | | sortOrder | "ASC" \| "DESC" | No | Initial sort | | filters | PastSubmissionsFilters | No | Initial filters | | searchTerm | string | No | Initial search value |

PastSubmissions is intentionally lighter than CP9's full in-app history workflow today. Rich Slate rendering, attachment rendering/uploading, reply recordings, and some deep-link/router orchestration still require host-specific work. See the parity matrix in @taskp3/sdk for the current drop-in status.

<Changelog>

Full changelog feed with type chips, descriptions, and expandable code changes.

<Changelog limit={10} types="New Feature,Bug fix" />

| Prop | Type | Default | Description | |---|---|---|---| | limit | number | 10 | Entries per page | | types | string | — | Comma-separated filter (e.g. "New Feature,Bug fix") | | className | string | — | CSS class on root container | | emptyText | string | "No changelog entries yet." | Text when no entries exist |

<WhatsNew>

Auto-showing modal for the latest changelog entry. Uses localStorage to track when the user last dismissed it — only re-appears when a newer release exists.

<WhatsNew onDismiss={(entry) => console.log("dismissed", entry.id)} />

| Prop | Type | Default | Description | |---|---|---|---| | storageKey | string | "p3-changelog-last-seen" | localStorage key for tracking | | onDismiss | (entry: ChangelogEntry) => void | — | Callback when user dismisses | | open | boolean | — | Force open/closed (overrides auto-show) |

Hooks

All hooks must be called inside <TaskP3Provider>.

useTriage()

Low-level hook for building fully custom triage UIs.

const { createTask, createResponse, uploadFile, getSubmissions, getResponses } = useTriage();

| Method | Returns | Description | |---|---|---| | createTask(data) | Promise<any> | Submit a triage task | | getSubmission(taskId) | Promise<TriageSubmission> | Get a single submission | | uploadFile(file) | Promise<TriageFileUpload & { localFile: File }> | Upload via presigned URL | | getSubmissions(params?) | Promise<TriageSubmissionsResponse> | List submissions (paginated) | | createResponse(taskId, data) | Promise<TriageSubmission> | Send a response | | getResponses(taskId, params?) | Promise<TriageResponsesResult> | List responses for a task | | createSubmissionFile(taskId, file) | Promise<TriageLinkedFileUploadResponse> | Attach file to submission | | createResponseFile(responseId, file) | Promise<TriageLinkedFileUploadResponse> | Attach file to response | | getFile(fileId) | Promise<TriageFile> | Get file metadata + presigned URL | | getSubmissionFiles(taskId, params?) | Promise<TriageFilesResponse> | List submission files | | getResponseFiles(responseId, params?) | Promise<TriageFilesResponse> | List response files |

usePastSubmissions(options?)

Stateful hook backing past-submissions workflows.

const {
  submissions,
  selectedTask,
  responses,
  responseDraft,
  setResponseDraft,
  sendResponse,
} = usePastSubmissions();

Deep-link example:

const taskIdFromQuery = new URLSearchParams(location.search).get("triageTaskId") ?? undefined;
const past = usePastSubmissions({ triageTaskId: taskIdFromQuery });

triageTaskId preselects a task in the modal workflow and fetches it directly when it is not part of the currently loaded page.

Migration Notes

  • Transcript polling/UI has been removed from @taskp3/react.
  • If you previously used transcript helpers/components, migrate that behavior to your own app-level API/UI implementation.

useChangelog(options?)

Fetches paginated changelog entries.

const { entries, isLoading, error, hasMore, loadMore } = useChangelog({ limit: 10 });

| Option | Type | Default | Description | |---|---|---|---| | limit | number | 10 | Entries per page | | types | string | — | Comma-separated type filter |

| Return | Type | Description | |---|---|---| | entries | ChangelogEntry[] | Loaded entries | | isLoading | boolean | True during fetch | | error | Error \| null | Fetch error, if any | | hasMore | boolean | More pages available | | loadMore | () => void | Load next page |

useChangelogCodeChanges(options)

Fetches paginated code changes for a single changelog entry.

const { codeChanges, isLoading, hasMore, loadMore } = useChangelogCodeChanges({
  entryId: entry.id,
  initialChanges: entry.codeChanges,
});

| Option | Type | Required | Description | |---|---|---|---| | entryId | string | Yes | Changelog entry ID | | initialChanges | ChangelogCodeChange[] | No | Pre-loaded changes (avoids duplicate fetch) | | limit | number | No | Changes per page (default 25) |

Theming

Pass a theme object to <TaskP3Provider>. Zero external CSS — all styles are injected automatically.

<TaskP3Provider
  apiUrl="https://your-app.com/api/triage"
  theme={{
    primaryColor: "#6366f1",
    primaryHoverColor: "#4f46e5",
    textOnPrimary: "#ffffff",
    fontFamily: "Inter, sans-serif",
    borderRadius: 12,
    zIndex: 10000,
    panelWidth: 440,
  }}
>
  {children}
</TaskP3Provider>

| Property | Type | Default | Description | |---|---|---|---| | primaryColor | string | "#1F93FF" | Primary brand color | | primaryHoverColor | string | "#0E7EE3" | Hover state | | textOnPrimary | string | "#ffffff" | Text color on primary backgrounds | | fontFamily | string | System font stack | CSS font-family | | borderRadius | number | 8 | Border radius in px | | zIndex | number | 9999 | Base z-index for floating elements | | panelWidth | number | 420 | Triage panel width in px |

Related Packages

| Package | Description | |---|---| | @taskp3/sdk | Server-side client + Express adapter | | @taskp3/react | React components — <TriageButton>, <Changelog>, <WhatsNew> |