Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

QR Scanner Dialog Block for React

An event check-in page with a simulated scanner dialog shown open: a viewfinder around a real sample QR code, a Wi-Fi, link and ticket payload read in turn, a result card that names the kind and cuts it into parts, a typed-code tab and a recent-scans strip.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Read what a code holds before anything acts on it, with this scanner dialog for React with Base UI. It opens from the Check-in page of Stubfold, an event check-in app: the page's header holds an outline Scan ticket Button, and the page, a count and a list of five guests, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The scanner is a simulation and says so on screen: no camera is used, no microphone, no permission is asked. In the Dialog a Tabs pair offers Camera, a viewfinder with four corner marks and a scan line around a real QR Code of a typed sample, and Enter code, a field for a pasted payload. Scan the sample code runs a short pass, with Stop, and takes three samples in turn: a link, a Wi-Fi code and a ticket. The result card names the kind in a Badge, Link, Wi-Fi, Ticket or Text, and cuts the payload into its parts, with a Copy Button on the host and the password. Check in Ada is the only Shine Button: it puts a ticket on the guest list as real text. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog.

FAQ

Why is the dialog already open, and what do I keep?

So you can see it without a click. On load the dialog is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Scan ticket button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same ScanFields component and share the block's state, so a scan made in the copy is there in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

Is a camera used, and is the QR code real?

No camera is opened, no microphone and no permission prompt, and the dialog says so under its title. The viewfinder is a drawing, and the code in it is a sample typed in the block. That code is a real QR code, drawn by the catalog component, so a phone pointed at the screen reads the same text the demo does. In your app read frames from a camera stream with a decoder and pass the decoded text to keep; everything after that, the reading, the card and the strip, stays as it is.

How does it tell the kinds apart?

readingOf looks at the text. A code that starts with WIFI: is a Wi-Fi code, cut at its semicolons into network, security and password. A web address becomes a link with its host and path. A line shaped like "Ticket 0417: Name, Admission" is a ticket, and anything else is plain text. A link is never followed: Open link says "Not opened in this demo", and a real app should show the host first and ask. A ticket that is not on the list, or is already in, says so and leaves the list alone.

What does the scan do, and can I stop it?

Scan the sample code starts a pass of a little over a second: the line sweeps down once, then the brackets close in on the code and the result card fills. Stop ends the pass early and nothing is read; it is always on the page and quiet until a pass runs. Under reduced motion the line holds still in the middle and the code is read at once. The next press takes the next sample, so the link, the Wi-Fi code and the ticket come round in turn. A polite message says what was read.

What stays local in the demo, and how do I wire it up?

Everything. The samples, the guest list and the recent scans are typed constants, the times are minutes on a typed clock, and checking a guest in changes only this page's state. In your app load the guests from your API, send the check-in from finish, and keep the guest's own record as the source for the strip.

Is it accessible from the keyboard?

Yes. The real dialog is named Scan a ticket, focus starts in the dialog and stays inside until it closes, and Escape and the close button return focus to Scan ticket. The two tabs move with the arrow keys, Enter in the code field reads it, and each recent scan is a button with a full name such as "Ticket, 0388, scanned 10:31". The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it and its close button close it and put focus on the button.

  • Pro

    Contact Card Dialog

    Share and invite

    A team directory with a contact card shown open that pages through six people: initials avatar, role, email, phone, desk and the time where they are, copy buttons, real mailto and tel links, and a Save contact button that downloads a vCard.

  • Pro

    A stock spreadsheet with its copy-as dialog shown open: the same four selected rows as Markdown, CSV, JSON or plain text, a preview that shows exactly what lands on the clipboard, a header-row option and a button that writes it.

  • Pro

    A family notes app's account page with a side sheet of signed-in devices shown open: this device pinned first, Sign out that asks inside the same row, and one button that signs out of all the others the same way.

  • Pro

    Two-Step Setup Dialog

    Account and security

    A cloud editor's security page with a three-step dialog shown open: a QR code and its key, eight backup codes to copy or download, and a six-digit check, ending in a note that two-step sign-in is on.

  • Pro

    Share Link Dialog

    Share and invite

    A prototype file with a share dialog shown open: a switch for anyone with the link, a read-only link whose role and expiry show in its suffix, a Copy link button that really copies, and a viewer preview that turns the file behind the dialog read-only.

  • Pro

    Media Upload Dialog

    Media and widgets

    A video library with its upload dialog shown open: a drop zone for images, video and audio that names the files it turns away and why, tiles for the ones that pass with a check each, bulk removal, a total and an Add button that puts the clips in the library.