@g9tm/lynxcontrols-barcode
G9BarcodeTextEntry: a scanner-aware text field (MAUI G9MAUIControls.Barcode). The camera is never this package's:
handle onScanRequested and drive your own scanner, or supply services.scanner and the field drives it. Depends on
@g9tm/lynxcontrols-foundation and @g9tm/lynxcontrols only; importing @g9tm/lynxcontrols never pulls it in. Migration table:
docs/migration/Barcode.Controls.md.
import { G9BarcodeTextEntry, type G9BarcodeTextEntryHandle } from '@g9tm/lynxcontrols-barcode';
// A: you own the camera (MAUI ScanRequested)
const field = useRef<G9BarcodeTextEntryHandle | null>(null);
<G9BarcodeTextEntry
ref={field}
label="Sample code"
acceptedCodeRegex="^\\d{3}/\\d{3}/\\d{6}$"
onScanRequested={async () => {
field.current?.startScan();
try {
field.current?.acceptScannedCode(await myScanner.scanOnce());
} finally {
field.current?.stopScan();
}
}}
onAccepted={(code) => model.add(code)}
/>
// B: services.scanner ({ isAvailable, scan }) does it: a tap scans; 'multiple' stays armed until cancelled
<G9BarcodeTextEntry label="Scanned items" scanMode="multiple" isEditable scanFormats={['code128']} />
Behaviour
- States
idle→scanBusy(spinner, read-only,scanBusyTextas placeholder) →accepted(success outline, ✓) orerror(error outline, ⓘ). The state is layered over your ownhasError,readOnly,useStatusColor,statusColor,placeholderandtrailingIcon; they come back when the state no longer needs them. Typing after a result returns the field toidle.scanStateis controllable. - Accepting.
acceptedCodeRegextakes a pattern string, aRegExpor a function. A malformed pattern or a throwing function rejects the code instead of throwing into the scan flow. Codes over 4096 characters are rejected before any pattern runs (MAUI bounded the match with a 250 ms regex timeout, which JavaScript cannot do).'single'replaces the text;'multiple'appends", code".onAcceptednever fires for typed text. - Scanner service. Without
onScanRequested, the scan icon is shown only whenservices.scanner.isAvailable()resolves true. A scan runs with an abort signal:stopScan()and unmount abort it and a late result is ignored;cancelledreturns toidle,deniedand failures becomeerror(failures also go to diagnostics). - Layout. The scan icon is pinned to the physical right and the text is pinned LTR in RTL pages (barcodes are left-to-right symbol strings); the label and outline follow the page direction.
Real scanner integration is a device check (plan/execution/Native-Validation-Pending.md N-045).