Component Structure
Relevant source files
The following files were used as context for generating this wiki page:The QR-Tool application is a single-page application built with React and Vite. Its architecture is centered around a main App component that manages the application's state, user interactions, and orchestrates several child components responsible for specific UI sections like the QR code preview and export functionality. The structure is largely monolithic within App.jsx, but it delegates rendering and specific logic to smaller, specialized components.
The application's logic is further supported by a set of utility functions for data generation, validation, and QR code export, as well as custom hooks for managing side effects like user preferences and notifications. This approach keeps the main component as the single source of truth while separating concerns into distinct, manageable files.
Sources: src/App.jsx, README.md
Core Architecture
The application's component hierarchy is straightforward, with App.jsx acting as the root container for all UI elements and logic.
This diagram shows the high-level relationship between the main App component and its primary children.
Key Components
| Component | File | Description |
|---|---|---|
App | src/App.jsx | The main application component. Manages all state, handles user input, and renders all other components. |
QrPreview | src/components/QrPreview.jsx | Renders the QR code preview using either <QRCodeCanvas> or <QRCodeSVG> from the qrcode.react library. |
ExportPanel | src/components/ExportPanel.jsx | Contains buttons and logic for downloading the generated QR code as a PNG, JPG, or SVG file. |
Input, Select, Button, Textarea | src/App.jsx | Generic, styled form components defined within App.jsx for consistent UI. |
ToastContainer | src/hooks/useToast.jsx | A container for displaying toast notifications, managed by the useToast hook. |
Sources: src/App.jsx:119-242, src/components/QrPreview.jsx, src/components/ExportPanel.jsx
App.jsx: The Core Component
App.jsx serves as the central controller of the application. It is responsible for:
- State Management: All application state, including QR type, data, and customization options (size, color, logo), is managed here using
React.useStateand theuseLocalStoragecustom hook. - QR Content Generation: It uses the
generateQRContentfunction to create the string that will be encoded into the QR code based on the currentqrTypeandqrData. - Input Validation: It performs real-time validation on user inputs (URL, email, etc.) and stores error states.
- Component Orchestration: It renders the input forms, the
QrPreviewcomponent, and theExportPanel, passing down the necessary props and state.
Sources: src/App.jsx
State Management
State is primarily managed through the useState hook. For user preferences that need to persist across sessions (like theme, UI mode, and QR settings), a custom useLocalStorage hook is employed.
// src/App.jsx:244-257
function useLocalStorage(key, initialValue, disabled = false) {
const [val, setVal] = React.useState(() => {
if (disabled) return initialValue;
try {
const v = localStorage.getItem(key);
return v !== null ? JSON.parse(v) : initialValue;
} catch {
return initialValue;
}
});
React.useEffect(() => {
if (disabled) return;
try {
localStorage.setItem(key, JSON.stringify(val));
} catch (error) {
console.warn('Failed to save to localStorage:', error);
}
}, [key, val, disabled]);
return [val, setVal];
}
This hook abstracts the logic for reading from and writing to the browser's localStorage.
Sources: src/App.jsx:244-257
Data Flow and QR Generation
The following sequence diagram illustrates the flow of data from user input to the final QR code preview update.
This flow demonstrates the reactive nature of the application, where UI updates are a direct result of state changes.
Sources: src/App.jsx:324-325, src/App.jsx:92-116, src/components/QrPreview.jsx
Child Components
QrPreview.jsx
This component is responsible for displaying the QR code. It dynamically switches between QRCodeCanvas and QRCodeSVG based on the format prop received from App.jsx. It also handles the drag-and-drop functionality for uploading a logo.
- Props: It receives a
qrPropsobject containing all necessary parameters for theqrcode.reactlibrary, such asvalue,size,level,fgColor,bgColor, andimageSettings. - Refs: It uses
canvasRefandsvgRefto provide direct access to the rendered QR code elements, which is crucial for the export functionality.
Sources: src/components/QrPreview.jsx:1-73
ExportPanel.jsx
This component manages the UI and logic for downloading the QR code. It presents buttons for PNG, JPG, and SVG formats, which are enabled or disabled based on the currently selected render format (canvas or svg).
The core logic resides in the handleDownload function, which performs the following steps:
- Retrieves the source
canvasorsvgelement using refs. - Checks if a "Quiet Zone" (margin) is missing and, if so, warns the user and adds a default padding to ensure scannability.
- Uses helper functions from
qr-helpers.js(buildDataURLfor canvas,buildSVGBlobfor SVG) to prepare the file data. - Triggers a download using the
downloadFilehelper. - Handles potential CORS errors if a logo from an external, non-permissive origin is used.
The following flowchart illustrates the export process:
Utilities and Hooks
The application relies on a set of helper functions and custom hooks to encapsulate reusable logic.
qr-helpers.js
This file is a collection of pure functions that support QR code generation, validation, and export.
| Function | Description |
|---|---|
isValidURL, isValidEmail, etc. | A suite of functions to validate user input formats. |
relLum, getContrastRatio | Calculates color contrast based on WCAG standards to warn users about poor color choices. |
pickECC | Automatically determines the optimal Error Correction Code (ECC) level based on logo size and color contrast. |
estimateDimension | Estimates the required QR code version (size in modules) based on content length and ECC level. |
buildDataURL, buildSVGBlob | Functions that take a raw canvas or SVG element and add padding or backgrounds before creating a downloadable file. |
The pickECC function logic is crucial for ensuring QR code scannability when a logo is added.
Custom Hooks
useToast: Manages a queue of toast notifications. TheAppcomponent callsshowToastto display messages for events like successful downloads or validation errors.useTheme: Handles the logic for toggling between light and dark modes and persists the user's choice inlocalStorage.useLocalStorage: A generic hook to synchronize a component's state withlocalStorage.useDebounced: Delays the update of a value, used to prevent re-rendering the QR code on every keystroke in text fields.
Sources: src/App.jsx:244-270, src/hooks/useToast.jsx