Skip to content
txbrendan/ui

QR Code

beta

A real, scannable QR code made on the device, as ink on a white tile in both themes, with its quiet zone built in.

Preview

pass

Ava Clarke

Demo day guest

Or check in by name, or with the code 7Q2K.

size

level

at least Lat least Mat least Qat least H

margin

poster

too long

Install

  1. 1. Add the registry to components.json, once per app. Without it, the shadcn CLI looks up @txbrendan in a public list that txbrendan/ui does not control.

    npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"
  2. 2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.

    npx shadcn@latest add @txbrendan/theme
  3. 3. Add the component.

    npx shadcn@latest add @txbrendan/qr-code

Use it for

  • A code people scan with a phone: a check-in, a join link, an event pass, a printed poster.
  • Pass value, usually a link, and aria-label, like 'Check-in code for the Workshop'.
  • Always pair it with another way in, like a short code to type or check-in by name. Nothing should be camera-only.
  • Pass className='w-full' for a poster. It scales as vector.
  • Use encodeQRCode(value) for the modules alone, to draw them some other way.

Avoid it for

  • A link people can click on the same screen. Show the link.
  • Long text, like a whole message. A long value makes a dense code that is hard to scan. Link to the text instead.
  • Secrets. Anyone who can see the code can read it.

Props

  • value

    Required. What the code holds, usually a link. It is encoded as UTF-8 bytes.

    string

  • aria-label

    Required. Names the code for screen readers, like 'Ava Clarke's guest pass'.

    string

  • size

    The most it draws: 120, 160, or 240px. Modules snap to whole pixels, so edges stay crisp.

    "sm" | "md" | "lg" · default "md"

  • level

    The least error correction. It rises for free while the data still fits the same size.

    "L" | "M" | "Q" | "H" · default "M"

  • margin

    The white quiet zone around the code, in modules. 4 is the standard's minimum.

    number · default 4

  • className

    Extra classes. Later classes win, so className='w-full max-w-none' fills a poster.

    string

Accessibility

  • Renders an <svg> with role="img", named by aria-label. TypeScript requires it.
  • The code is ink on a white tile in light and dark, since many phone cameras cannot read a light code on dark.
  • A value too long for any code shows an empty dashed tile, and its name says so.
  • Screen readers cannot read the code itself. Put the link or a short code beside it as text.

Examples

A pass, named for screen readers

<QRCode value="https://example.com/p/ava-clarke-7q2k" aria-label="Ava Clarke's guest pass" />

With another way in

<div className="flex items-center gap-4">
  <QRCode value="https://example.com/check-in/4821" aria-label="Check-in code for the Workshop" size="sm" />
  <p>Or type the code 4821 at the door.</p>
</div>

For a poster

<QRCode value="https://example.com/join" aria-label="Join the team" level="H" className="w-full max-w-none" />