Barcode
oge-barcode draws QR codes, Code 128 and EAN-13 barcodes; oge-barcode-scanner reads them from the camera or an image file.
The encoders are the suite's own — no dependency, no canvas: a QR code picks its mode, the smallest version and the lowest-penalty mask, and was checked against an independent reader across modes, levels, masks and sizes up to version 40. Symbols are crisp SVG named by their value. Reading uses the browser's BarcodeDetector where it exists; elsewhere you pass a decoder.
Generate
Type a value and pick a symbology. A value the symbology cannot hold — letters in an EAN-13, a character outside printable ASCII in Code 128 — shows a message instead of a symbol.
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { OgeBarcode } from '@oge-ui/layout';
import type { OgeBarcodeType } from '@oge-ui/layout';
@Component({
selector: 'demo-root',
imports: [OgeBarcode],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- A crisp SVG named by its value; a value the symbology cannot hold
shows a message instead. download() saves the symbol as an SVG file. -->
<input [value]="value()" (input)="value.set($any($event.target).value)" aria-label="Value" />
@for (t of types; track t) {
<button type="button" [attr.aria-pressed]="type() === t" (click)="type.set(t)">{{ t }}</button>
}
<oge-barcode #code [value]="value()" [type]="type()" [scale]="3" />
<button type="button" (click)="code.download('barcode.svg')">Download SVG</button>
`,
})
export class Demo {
protected readonly value = signal('https://ogeui.com');
protected readonly type = signal<OgeBarcodeType>('qr');
protected readonly types: OgeBarcodeType[] = ['qr', 'code128', 'ean13'];
}Labels
EAN-13 adds its own check digit; a QR code at level H still reads with 30 % of it scuffed; bars take a height and a colour (keep them dark on light).
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeBarcode } from '@oge-ui/layout';
@Component({
selector: 'demo-root',
imports: [OgeBarcode],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- A product label: EAN-13 adds its own check digit; the QR code uses
the highest error correction, so a scuffed label still reads. -->
<oge-barcode type="ean13" value="400638133393" [scale]="2" />
<oge-barcode value="SKU-2041 · Lot 7" errorCorrection="H" [scale]="3" />
<oge-barcode type="code128" value="SHIP-000123" [barHeight]="30" color="#1e3a8a" />
`,
})
export class Demo {}Scan
Start opens the camera and reads a frame every 250 ms — a value read again within a moment counts once; “Scan an image” reads a file. A polite status line announces each read, and says so when the browser has no reader or the camera is refused.
Nothing read yet
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { OgeBarcodeScanner } from '@oge-ui/layout';
import type { OgeBarcodeResult } from '@oge-ui/layout';
@Component({
selector: 'demo-root',
imports: [OgeBarcodeScanner],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- Start opens the camera; "Scan an image" reads a file. Reading uses the
browser's BarcodeDetector — pass [decoder] where there is none. -->
<oge-barcode-scanner (detected)="onRead($event)" />
<p>{{ last() }}</p>
`,
})
export class Demo {
protected readonly last = signal('Nothing read yet');
protected onRead(result: OgeBarcodeResult): void {
this.last.set(`${result.format}: ${result.value}`);
}
}