Skip to content
Cynosurev0.5.0
SearchStorybookGitHubnpmColour mode: System. Switch to Light

Components / More

QRCode

A QR code drawn as one crisp SVG path, so a phone can open a link shown on a bigger screen. It stays dark on light in every colour mode, because many phone cameras cannot read an inverted code.

Default

When to useLink to "When to use"

  • Desktop to phone: a link to the mobile app, the extension store or a sign-in page, on a page people read on a computer.
  • Sharing: an invite or a document link in a sharing panel.
  • Print and slides: where nobody can click a link.

Use something else when:

  • people are already on their phone: a Link or a Button with href
  • the link should be copied: CopyButton

UsageLink to "Usage"

tsx
Copy
import { Icon, QRCode } from "@arshad-shah/cynosure";
import { globe } from "@arshad-shah/cynosure/icons";

<QRCode value="https://cynosure.arshadshah.com" label="Open the documentation on your phone" />
<QRCode value={inviteUrl} size="lg" icon={<Icon icon={globe} />} />
<QRCode value={text} size={240} level="Q" />

size is sm, md (default) or lg, or a number of pixels. The code is never wider than its container and is always square. A longer value needs a denser code, drawn in the same box.

Sizes and pixels

Error correctionLink to "Error correction"

level says how much of the code can be lost and still scan: L 7%, M 15% (default), Q 25%, H 30%. A higher level needs a denser code. Use Q or H for print that may get scuffed.

Error correction levels

A logo in the middleLink to "A logo in the middle"

icon draws a logo in the centre on the light colour. It covers modules, so the level is raised to H whatever level says. The icon box is 20% of the width (--cy-qr-code-icon-size); keep it at 22% or less.

With acentred icon

Dark modeLink to "Dark mode"

The code keeps dark modules on a light square in dark mode. The root sets color-scheme: light, so the theme's colours resolve to the light palette's ink and surface inside it, and the light quiet zone sets the code apart from the dark page. To change the colours, set --cy-qr-code-color and --cy-qr-code-background together and keep the modules darker than the background (4.5:1 or more).

Dark on light in every mode

Without ReactLink to "Without React"

The encoder is exported for Astro components, static HTML and files:

ts
Copy
import { qrMatrix, qrPath, qrToSvg } from "@arshad-shah/cynosure";

// A standalone SVG with its colours written in (black on white unless `color` and `background` say otherwise).
qrToSvg("https://example.com", { size: 160, label: "Example", level: "Q", quietZone: 4 });

// The modules as rows of booleans (true is dark), without the quiet zone.
const matrix = qrMatrix("HELLO", { level: "Q" });

// Path data, one unit per module, offset by the quiet zone: use it in your own <svg viewBox>.
qrPath(matrix, 4);

qrMatrix picks the smallest version that holds the text, in numeric, alphanumeric or UTF-8 byte mode. It throws a RangeError when the text does not fit in version 40 (2,953 bytes at L, 1,273 at H).

PropsLink to "Props"

Every prop of QRCode
PropWhat it doesTypeDefault
valueRequired
The text to encode, usually a URL. Numbers and upper-case text use the compact modes; anything else is UTF-8.string
size
Width and height: sm, md (default) or lg from the tokens, or a number of pixels.number | Size
level
Error correction: how much of the code can be damaged or covered and still scan (L 7%, M 15%, Q 25%, H 30%). Higher levels need a denser code. Default "M"; always "H" with an icon.QrLevel"M"
quietZone
Light modules around the code, which scanners need to find it. The standard asks for 4. Default 4.number4
label
Accessible name. Default labels.name ("QR code"). Say where it leads, and show the link as text too.string`labels
labels
Built-in strings.Partial<QRCodeLabels>
icon
A logo drawn in the centre, on the light colour (an <Icon> or a small image). It covers modules, so the level is raised to H.ReactNode
className
Added to the root element, for layout.string
style
Layout only. Restyle through --cy-qr-code-* tokens.CSSProperties

Generated from the type definitions in @arshad-shah/cynosure 0.5.0.

Behaviour and accessibilityLink to "Behaviour and accessibility"

Behaviour and accessibility, table 1
SituationResult
Any valueEvery module of the encoder's matrix is drawn, in one path, with quietZone light modules around it
icon is setThe level is H and the icon sits in the middle on the light colour
Dark modeSame colours as light mode: dark modules on a light square
Right-to-leftNothing is mirrored
The container is narrower than sizeThe code shrinks to fit and stays square
  • Semantics: the root is one image (role="img") named "QR code" by default. Set label to say where it leads, or labels.name to translate the default. The SVG and the icon inside are hidden.
  • Show the link too. A screen reader user cannot scan the code, and some people cannot hold a phone to the screen.
  • Keyboard: nothing to focus.

TouchLink to "Touch"

Nothing in QRCode can be pressed.

ThemingLink to "Theming"

Tokens: --cy-qr-code-color (dark modules), --cy-qr-code-background (light modules and the quiet zone), --cy-qr-code-size-sm, --cy-qr-code-size-md, --cy-qr-code-size-lg, --cy-qr-code-icon-size and --cy-qr-code-radius.

ts
Copy
createTheme({ components: { qrCode: { color: "#0b2545", radius: "0px" } } });

Link · CopyButton · DeviceFrame

These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.

Getting started
Theming
Icons
Accessibility
Code editors and highlighters
Using Cynosure without React
Build-tool adapters
Components
Accordion
AppShell
AspectRatio
Breadcrumbs
Calendar
Card
Container
Disclosure
Divider
DocumentViewport
Grid
Inline
PageHeader
PanZoomCanvas
ScrollArea
SideNav
SortableList
SplitPane
Stack
StatusBar
Tabs
TitleBar
Toolbar
Tree
VirtualList
ZoomControls
Announcer
Avatar
Badge
CodeBlock
DescriptionList
EmptyState
ErrorBoundary
Field
Heading
IconTile
Image
Kbd
List
LoadingDots
Notice
ProgressBar
Prose
Skeleton
Stat
Steps
Table
Text
Button
Checkbox
Checklist
ColorField
ColorSwatches
Combobox
CompareSlider
CopyButton
DateField
FileDrop
IconButton
KeyValueEditor
Link
NumberField
Pagination
PathField
RadioGroup
SearchField
SegmentedControl
Select
SelectionFrame
SignaturePad
Slider
Switch
TagInput
TextArea
TextField
ThemeToggle
TimeField
ButtonBase
ChoiceBase
DialogBase
FileInputBase
HiddenValue
Icon
InputBase
LinkBase
LiveRegion
TextAreaBase
ChatMessage
Choice
DataGrid
DeviceFrame
HighlightedText
HotkeyField
ListRow
OptionList
OverlayFrame
QRCode
RowActions
Section
SiteFooter
SiteHeader
SkipLink
SortButton
VisuallyHidden
CommandPalette
ContextMenu
Dialog
FloatingToolbar
HoverCard
Menu
Menubar
Popover
ProgressOverlay
Sheet
Toast
Tooltip
Changelog