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

@scanupload/qr-code-generator

v0.1.7

Published

A reusable qr-code-generator library using Tailwind CSS v4, React, and Vite for the ScanUpload SAAS application.

Readme

@scanupload/qr-code-generator

A React component that displays a QR code allowing a mobile device to securely upload files to a ScanUpload session. Once a mobile user scans the QR code and uploads files, the desktop component receives real-time status updates via a SignalR connection and renders a live preview of every uploaded file.


Backend-end integrations

This official react client library is designed to work seamlessly with the ScanUpload backend proxy:

Table of Contents

Installation

The package is distributed as an ES module and CJS bundle with bundled CSS.

npm install @scanupload/qr-code-generator

Peer dependencies

| Package | Version | | ----------- | ------- | | react | >= 19 | | react-dom | >= 19 |

Import the stylesheet

import "@scanupload/qr-code-generator/dist/index.css";

Backend API Requirements

The component communicates with two endpoints on your client backend proxy (a .NET application — see ScanUpload.Api.Client on NuGet). The proxy is responsible for authenticating with the ScanUpload Auth Server using OAuth 2.0 client credentials and forwarding requests to the ScanUpload Hub. The component never holds client credentials — it only receives short-lived Bearer tokens.

The SignalR WebSocket is the exception. The WebSocket connection to hubUrl is opened directly from the browser to the ScanUpload Hub — it does not pass through your proxy.

flowchart LR
    subgraph Client["Client (SAAS)"]
        D["🖥️ Client Front End"]
        P["🔁 Client Backend Proxy"]
    end

    subgraph ScanUpload["ScanUpload"]
        Auth["🔐 Auth Server"]
        Hub["ScanUpload Hub"]
    end

    D -->|"POST sessionUrl"| P
    D -->|"POST refreshTokenUrl"| P
    P -->|"client credentials"| Auth
    Auth -->|"access_token"| P
    P -->|"authenticated request"| Hub
    Hub -->|"response"| P
    P -->|"response"| D
    D --->|"WebSocket direct"| Hub

Usage

import { QrCodeGenerator } from "@scanupload/qr-code-generator";
import "@scanupload/qr-code-generator/dist/index.css";

export default function App() {
  return (
    <div className="flex items-center justify-center min-h-screen bg-gray-100">
      <form className="bg-white shadow-lg rounded-lg p-8 max-w-md">
        <QrCodeGenerator
          sessionUrl="/scanupload-api/session"
          refreshTokenUrl="/scanupload-api/token"
          showHeader={true}
          header="Upload files from mobile device"
          size="large"
          showLogo={true}
          clickQrCodeToReload={true}
          filePreviewMode="list"
          classNames={{
            qrWrapper: "rounded-none border-solid border-blue-500",
            reloadButton: "bg-red-500 hover:bg-red-700",
            header: "text-2xl font-bold text-purple-700",
          }}
        />
      </form>
    </div>
  );
}

Props Reference

| Prop | Type | Default | Required | Description | | --------------------- | -------------------------------------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | sessionUrl | string | — | ✅ | URL of the endpoint that creates a ScanUpload session (POST). | | refreshTokenUrl | string | — | ✅ | URL of the endpoint that returns a fresh Bearer token (POST). | | header | string | — | ✅ | Text rendered in the header element (visible only when showHeader is true). | | showHeader | boolean | false | | Whether to render the header above the QR code. | | showLogo | boolean | true | | Whether to overlay the ScanUpload logo in the centre of the QR code. | | clickQrCodeToReload | boolean | false | | When true, clicking the QR code triggers a session reload. When false, a separate Reload button is shown beneath the QR code instead. | | size | "small" \| "medium" \| "large" \| "xlarge" | "large" | | Controls the overall size of the QR code container. | | filePreviewMode | "list" \| "grid" | "grid" | | How uploaded files are displayed — as a grid of document tiles or a compact list. | | classNames | QrCodeClassNames | {} | | Slot-based Tailwind class overrides. See classNames Customisation. | | style | React.CSSProperties | — | | Inline styles applied to the root <section>. Useful for injecting CSS custom properties. |


classNames Customisation

Each key targets a specific UI region. Classes are merged with the built-in defaults using tailwind-merge, so any Tailwind conflicts are always resolved in favour of the override you supply.

| Key | Element | Description | | ---------------- | ----------- | -------------------------------------------------------------------------- | | root | <section> | Outermost wrapper of the component. | | loadingOverlay | <div> | Spinner overlay shown while the session is being created. | | errorOverlay | <div> | Overlay shown when the session could not be created. | | errorButton | <button> | Retry button inside the error overlay. | | header | <h1> | The header text element. | | qrWrapper | <div> | Bordered box that wraps the QR code. | | reloadButton | <button> | Reload button shown when clickQrCodeToReload is false. | | hintText | <p> | "Click QR code to reload" hint shown when clickQrCodeToReload is true. | | fileContainer | <div> | Container for the file grid or list. |

Example

<QrCodeGenerator
  classNames={{
    qrWrapper: "rounded-none border-solid border-blue-500",
    reloadButton: "bg-red-500 hover:bg-red-700",
    header: "text-2xl font-bold text-purple-700",
  }}
  ...
/>

CSS custom properties

Use style to inject design tokens:

<QrCodeGenerator
  style={{
    "--qr-accent": "#1d4ed8",
    "--qr-border": "#d1d5db",
  } as React.CSSProperties}
  ...
/>

File Preview Modes

"grid" (default)

Renders each file as a DocumentPreviewer tile with:

  • A file-type icon colour-coded by extension (PDF → red, Word → blue, Excel → green, images → purple, etc.)
  • A thumbnail for image files (when thumbnailBase64 is provided by the server)
  • An upload progress bar

"list"

Renders all files as a compact FileList with:

  • A 48 × 48 thumbnail (or a generic document icon if no thumbnail is available)
  • File name (truncated) and size in KB

License

MIT © Donald Asante