QR code
A QR code drawn dark on a light panel in every theme from the kit's own encoder, such as the code that joins the guest Wi-Fi network.
On this page
Guest Wi-Fi
- Network
- Althea Guest
- Password
- harbor-lantern-41
Code
import { Card } from "@bosunkit/components/card";
import { QrCode, wifiNetworkText } from "@bosunkit/components/qr-code";
import type { ReactElement } from "react";
export const description: string =
"The guest network's join code on the vessel's welcome card: a phone's camera reads it and offers to join Althea " +
"Guest, with the password written beside it for a phone that does not.";
export default function Showcase(): ReactElement {
return (
<Card title="Guest Wi-Fi" style={{ width: "100%", maxWidth: 420 }}>
<div style={{ display: "flex", flexWrap: "wrap", alignItems: "center", gap: "var(--space-lg)" }}>
<QrCode
value={wifiNetworkText({ ssid: "Althea Guest", password: "harbor-lantern-41" })}
label="Code to join Althea Guest with a phone's camera"
/>
<dl style={{ margin: 0, display: "grid", gap: "var(--space-xs)" }}>
<dt>Network</dt>
<dd style={{ margin: 0, fontFamily: "var(--font-mono)" }}>Althea Guest</dd>
<dt>Password</dt>
<dd style={{ margin: 0, fontFamily: "var(--font-mono)" }}>harbor-lantern-41</dd>
</dl>
</div>
</Card>
);
}
A QR code draws a text as a square of modules that a phone's camera reads. The kit encodes it itself (byte mode,
UTF-8, versions 1 to 40, the mask with the lowest penalty), and its output is pinned against two independent
encoders. The dark modules are one SVG path on a light panel of its own that holds the four-module quiet zone a
reader needs (ISO/IEC 18004, section 9.1). The panel and the modules swap the theme's background and text colors, so
the modules are always the darker: the text on the background in Day and Bright, the background on the text in Dusk
and Night. Many phone cameras fail to read a light-on-dark code, and in Night the panel is no brighter than the text
already on the screen. Each module covers a whole number of device pixels: the panel is drawn at the largest size
inside size at which it does, centered, so no module is a pixel wider than its neighbor. The code is an image named
by label, which says what scanning it does.
wifiNetworkText({ ssid, password }) writes the text that joins a WPA or WPA2 network,
WIFI:T:WPA;S:<ssid>;P:<password>;;, with each \, ;, ,, : and " in the name and the password escaped
with a backslash. iOS and Android cameras offer to join the network it names.
Examples
Sizes
Code
import { QrCode } from "@bosunkit/components/qr-code";
import type { ReactElement } from "react";
export const description: string =
"`size` sets the side of the code's box as a CSS length; the panel is the largest inside it whose modules cover " +
"whole device pixels, and the quiet zone scales with them.";
export default function Sizes(): ReactElement {
return (
<div style={{ display: "flex", flexWrap: "wrap", alignItems: "end", gap: "var(--space-lg)" }}>
<QrCode value="https://bosun.bot" label="Code for bosun.bot, small" size="6em" />
<QrCode value="https://bosun.bot" label="Code for bosun.bot" />
<QrCode value="https://bosun.bot" label="Code for bosun.bot, large" size="14em" />
</div>
);
}
Themes
Code
import { Card } from "@bosunkit/components/card";
import { QrCode, wifiNetworkText } from "@bosunkit/components/qr-code";
import { PresentationScope } from "@bosunkit/provider";
import type { Theme } from "@bosunkit/tokens/theme";
import type { ReactElement } from "react";
export const description: string =
"The guest network's code in each of the four themes: dark modules on a light panel every time, the panel in " +
"Night the Night text color, so it is no brighter than the text around it.";
const THEMES: readonly { readonly theme: Theme; readonly name: string }[] = [
{ theme: "night", name: "Night" },
{ theme: "dusk", name: "Dusk" },
{ theme: "day", name: "Day" },
{ theme: "bright", name: "Bright" },
];
export default function Themes(): ReactElement {
return (
<div
style={{ width: "100%", display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(10em, 1fr))", gap: 10 }}
>
{THEMES.map((entry: { readonly theme: Theme; readonly name: string }): ReactElement => (
<PresentationScope key={entry.theme} theme={entry.theme}>
<Card footer={entry.name}>
<QrCode
value={wifiNetworkText({ ssid: "Althea Guest", password: "harbor-lantern-41" })}
label={`Code to join Althea Guest with a phone's camera, in ${entry.name}`}
size="8em"
/>
</Card>
</PresentationScope>
))}
</div>
);
}
Error correction
Code
import { QrCode } from "@bosunkit/components/qr-code";
import type { ReactElement } from "react";
export const description: string =
"The same text at levels L, M, Q and H: more error correction takes more modules, and reads through a smudge or " +
"a fold on a printed card.";
export default function ErrorCorrection(): ReactElement {
return (
<div style={{ display: "flex", flexWrap: "wrap", alignItems: "end", gap: "var(--space-lg)" }}>
<QrCode
value="https://bosun.bot/althea"
label="Code for the vessel's page, level L"
errorCorrection="L"
size="7em"
/>
<QrCode value="https://bosun.bot/althea" label="Code for the vessel's page, level M" size="7em" />
<QrCode
value="https://bosun.bot/althea"
label="Code for the vessel's page, level Q"
errorCorrection="Q"
size="7em"
/>
<QrCode
value="https://bosun.bot/althea"
label="Code for the vessel's page, level H"
errorCorrection="H"
size="7em"
/>
</div>
);
}
A visible alternative to scanning
Keep the destination or pairing instruction beside the code. Scanning is unavailable to some readers and can fail because of glare, camera focus or another device's display. Do not make a QR code the only route to required information. Verify the actual printed or displayed size with a real camera.
Treat an embedded secret or pairing token as sensitive content: the picture can be photographed, cached or copied. The caller owns authorization, expiry and any regeneration. A valid QR encoding does not establish that its payload is safe to share or that the destination remains available.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| valuerequired | string | – | The text the code holds, such as wifiNetworkText({ ssid, password }) for a network's join code. |
| labelrequired | string | – | What the code is for, as its accessible name: "Code to join Althea Guest with a phone's camera". |
| errorCorrection | QrErrorCorrection | undefined | "M" | How much of the symbol can be damaged and still read; M (about 15 %) by default. |
| size | string | undefined | "10em" | The width and height of the box the code takes, as a CSS length; 10em by default. The panel is drawn at the largest size inside it whose modules cover whole device pixels, centered. |
| className | string | undefined | – | Classes added to the <svg>. |
| testId | string | undefined | – | data-testid on the <svg>. |
| ref | Ref<SVGSVGElement> | undefined | – | The <svg> element. |
Sources: ZXing, Barcode contents: Wi-Fi network config; Project Nayuki, QR Code generator library.
Related
- Setting control: the guest Wi-Fi password row that shows this code.
- Password input: the field the network's password is typed in.