# Phone Barcode Scanner — Library Refactor Plan ## Goal Refactor the current monolithic app into a reusable library that can be embedded as a feature in other applications, with a clean API and self-contained UI. ## Project Structure ``` phone-barcode/ lib/ scanner.mjs — camera, decode pipeline, ZXing wrapper (no DOM) scanner-ui.mjs — clones template node into a container, wires controls template.html — UI markup fragment (no /, just the widget) style.css — scoped styles for the widget index.mjs — public API (re-exports) vendor/ zxing.min.js — bundled, populated by `make build` demo/ index.html — demo app, built as a consumer of the library app.mjs Makefile package.json ``` ## API ### Low-level: bring your own container ```javascript import { Barcode_Scanner } from './phone-barcode/index.mjs'; const scanner = new Barcode_Scanner(container_el, { mode: 'continuous', // 'continuous' | 'single' | 'aim-tap' on_scan(text, format) {}, // called on each successful decode on_close() {}, // called when user dismisses }); await scanner.start(); scanner.stop(); ``` The scanner clones the UI template into `container_el` and takes it over. Caller is responsible for showing/hiding the container. ### High-level: managed dialog ```javascript import { scan_once, scan_continuous } from './phone-barcode/index.mjs'; // Creates a , runs scanner, resolves on first scan, cleans up const result = await scan_once(); // → { text: '...', format: 'CODE_128' } | null (if dismissed) // Same but keeps scanning; on_scan called for each result const handle = await scan_continuous({ on_scan(text, format) {} }); handle.close(); ``` Both functions create a `` internally, inject the scanner, and manage the full lifecycle. They accept an optional `dialog_el` parameter if the caller wants to provide their own dialog element instead. ## Template Loading The UI template (`template.html`) is a plain HTML fragment — no `` or ``, just the widget markup. Two ways to get the template node: ```javascript // 1. Library fetches it (convenience) import { load_template } from './phone-barcode/index.mjs'; const tmpl = await load_template(); // fetches template.html relative to lib // 2. Caller provides it (e.g. already in the DOM, or loaded differently) const tmpl = document.getElementById('barcode-scanner-template'); const scanner = new Barcode_Scanner(container, { template: tmpl }); ``` `Barcode_Scanner` accepts either a `