Components
QR Code
Renders a QR code as a single SVG path, using the qrcode package's synchronous encoder.
Installation
npx kosmesis add qr-codepnpm dlx kosmesis add qr-codeyarn dlx kosmesis add qr-codebunx kosmesis add qr-codeInstall the following dependencies:
npm install qrcodepnpm add qrcodeyarn add qrcodebun add qrcodeCopy and paste the following code into your project.
import { create as createQRCode, type QRCodeErrorCorrectionLevel } from "qrcode";import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import { cn } from "@/lib/utils";export interface QRCodeProps { value: string; size?: number; margin?: number; errorCorrectionLevel?: QRCodeErrorCorrectionLevel; color?: string; background?: string; class?: string; id?: string; "aria-label"?: string;}// Renders as a single SVG path (not one <rect> per module) since a real QR code can have thousands of modules.// Colors default to fixed black-on-white, not theme tokens, so the code keeps scanning contrast regardless of theme.@Component()export class QRCode extends StatelessComponent<QRCodeProps> { render() { const { value, size = 200, margin = 2, errorCorrectionLevel = "medium", color = "#000000", background = "#ffffff", class: cls, id, "aria-label": ariaLabel, } = this.props; const code = createQRCode(value, { errorCorrectionLevel }); const moduleCount = code.modules.size; const total = moduleCount + margin * 2; let path = ""; for (let row = 0; row < moduleCount; row++) { for (let col = 0; col < moduleCount; col++) { if (code.modules.get(row, col)) { path += `M${String(col + margin)} ${String(row + margin)}h1v1h-1z`; } } } return ( <svg id={id} viewBox={`0 0 ${String(total)} ${String(total)}`} width={size} height={size} role="img" aria-label={ariaLabel ?? `QR code for ${value}`} shape-rendering="crispEdges" class={cn("shrink-0", cls)} > <rect width={total} height={total} fill={background} /> <path d={path} fill={color} /> </svg> ); }}Install the following dependencies:
npm install qrcode @praxisjs/csspnpm add qrcode @praxisjs/cssyarn add qrcode @praxisjs/cssbun add qrcode @praxisjs/cssCopy and paste the following code into your project.
import { create as createQRCode, type QRCodeErrorCorrectionLevel } from "qrcode";import { StatelessComponent } from "@praxisjs/core";import { cx, Stylesheet, Styled } from "@praxisjs/css";import { Component } from "@praxisjs/decorators";class QRCodeStyles extends Stylesheet { $root = this.css({ flexShrink: 0 });}export interface QRCodeProps { value: string; size?: number; margin?: number; errorCorrectionLevel?: QRCodeErrorCorrectionLevel; color?: string; background?: string; class?: string; id?: string; "aria-label"?: string;}// Renders as a single SVG path (not one <rect> per module) since a real QR code can have thousands of modules.// Colors default to fixed black-on-white, not theme tokens, so the code keeps scanning contrast regardless of theme.@Component()export class QRCode extends StatelessComponent<QRCodeProps> { @Styled(QRCodeStyles) $s!: QRCodeStyles; render() { const { value, size = 200, margin = 2, errorCorrectionLevel = "medium", color = "#000000", background = "#ffffff", class: cls, id, "aria-label": ariaLabel, } = this.props; const code = createQRCode(value, { errorCorrectionLevel }); const moduleCount = code.modules.size; const total = moduleCount + margin * 2; let path = ""; for (let row = 0; row < moduleCount; row++) { for (let col = 0; col < moduleCount; col++) { if (code.modules.get(row, col)) { path += `M${String(col + margin)} ${String(row + margin)}h1v1h-1z`; } } } return ( <svg id={id} viewBox={`0 0 ${String(total)} ${String(total)}`} width={size} height={size} role="img" aria-label={ariaLabel ?? `QR code for ${value}`} shape-rendering="crispEdges" class={cx(this.$s.$root, cls)} > <rect width={total} height={total} fill={background} /> <path d={path} fill={color} /> </svg> ); }}Examples
About
Purely presentational. Uses the qrcode package's
synchronous create() encoder and renders every dark module as a single combined SVG <path>
(not one <rect> per module — a real QR code can have thousands). Colors default to a fixed
black-on-white rather than the theme's tokens, so the code keeps scanning contrast regardless of
light/dark theme.
Usage
import { QRCode } from "@/components/ui/qr-code";
<QRCode value="https://example.com" size={180} />Props
| Prop | Type | Default |
|---|---|---|
value | string | — |
size | number | 200 |
margin | number | 2 |
errorCorrectionLevel | "low" | "medium" | "quartile" | "high" | "medium" |
color | string | "#000000" |
background | string | "#ffffff" |
class | string | — |