@larscom/ng-qrcode-svg
Version:
Simple QR code generator (SVG only) for Angular
102 lines • 11.1 kB
JavaScript
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { Ecc, QrCode } from './qrcode-generator';
import * as i0 from "@angular/core";
const VALID_COLOR_REGEX = /^#(?:[0-9a-fA-F]{3,4}){1,2}$/;
export class QrcodeSvgComponent {
constructor() {
this.ecl = 'medium';
this.borderSize = 2;
this.size = 250;
this.backgroundColor = '#FFFFFF';
this.foregroundColor = '#000000';
}
ngOnChanges(changes) {
this.validateInputs();
if (this.skipUpdate(changes))
return;
this.qr = QrCode.encodeText(this.value, Ecc[this.ecl]);
const s = this.qr.size + this.borderSize * 2;
this.viewBox = `0 0 ${s} ${s}`;
this.d = this.createD(this.borderSize);
}
validateInputs() {
if (!this.value)
throw Error('[@larscom/ng-qrcode-svg] You must provide a value!');
if (!VALID_COLOR_REGEX.test(this.backgroundColor))
throw Error('[@larscom/ng-qrcode-svg] You must provide a valid backgroundColor (HEX RGB) eg: #FFFFFF');
if (!VALID_COLOR_REGEX.test(this.foregroundColor))
throw Error('[@larscom/ng-qrcode-svg] You must provide a valid foregroundColor (HEX RGB) eg: #000000');
}
skipUpdate({ backgroundColor, foregroundColor, size }) {
const bgColorChanged = backgroundColor?.currentValue && !backgroundColor?.firstChange;
const fgColorChanged = foregroundColor?.currentValue && !foregroundColor.firstChange;
const sizeChanged = size?.currentValue && !size.firstChange;
return bgColorChanged || fgColorChanged || sizeChanged;
}
createD(borderSize) {
const parts = [];
for (let y = 0; y < this.qr.size; y++) {
for (let x = 0; x < this.qr.size; x++) {
if (this.qr.getModule(x, y))
parts.push(`M${x + borderSize},${y + borderSize}h1v1h-1z`);
}
}
return parts.join(' ');
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QrcodeSvgComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: QrcodeSvgComponent, isStandalone: true, selector: "qrcode-svg", inputs: { value: "value", ecl: "ecl", borderSize: "borderSize", size: "size", backgroundColor: "backgroundColor", foregroundColor: "foregroundColor", alt: "alt", ariaLabel: "ariaLabel" }, usesOnChanges: true, ngImport: i0, template: `
<svg
xmlns="http://www.w3.org/2000/svg"
version="1.1"
stroke="none"
[attr.alt]="alt"
[attr.aria-label]="ariaLabel"
[attr.width]="size"
[attr.height]="size"
[attr.viewBox]="viewBox"
>
<rect width="100%" height="100%" [attr.fill]="backgroundColor" />
<path [attr.d]="d" [attr.fill]="foregroundColor" />
</svg>
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QrcodeSvgComponent, decorators: [{
type: Component,
args: [{
selector: 'qrcode-svg',
standalone: true,
template: `
<svg
xmlns="http://www.w3.org/2000/svg"
version="1.1"
stroke="none"
[attr.alt]="alt"
[attr.aria-label]="ariaLabel"
[attr.width]="size"
[attr.height]="size"
[attr.viewBox]="viewBox"
>
<rect width="100%" height="100%" [attr.fill]="backgroundColor" />
<path [attr.d]="d" [attr.fill]="foregroundColor" />
</svg>
`,
changeDetection: ChangeDetectionStrategy.OnPush
}]
}], propDecorators: { value: [{
type: Input
}], ecl: [{
type: Input
}], borderSize: [{
type: Input
}], size: [{
type: Input
}], backgroundColor: [{
type: Input
}], foregroundColor: [{
type: Input
}], alt: [{
type: Input
}], ariaLabel: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXJjb2RlLXN2Zy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1xcmNvZGUtc3ZnL3NyYy9saWIvcXJjb2RlLXN2Zy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQTRCLE1BQU0sZUFBZSxDQUFBO0FBQ25HLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUE7O0FBRWhELE1BQU0saUJBQWlCLEdBQUcsOEJBQThCLENBQUE7QUFzQnhELE1BQU0sT0FBTyxrQkFBa0I7SUFwQi9CO1FBc0JXLFFBQUcsR0FBMkMsUUFBUSxDQUFBO1FBQ3RELGVBQVUsR0FBRyxDQUFDLENBQUE7UUFFZCxTQUFJLEdBQW9CLEdBQUcsQ0FBQTtRQUMzQixvQkFBZSxHQUFHLFNBQVMsQ0FBQTtRQUMzQixvQkFBZSxHQUFHLFNBQVMsQ0FBQTtLQWdEckM7SUF0Q0MsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQTtRQUVyQixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDO1lBQUUsT0FBTTtRQUVwQyxJQUFJLENBQUMsRUFBRSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFDdEQsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUE7UUFDNUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQTtRQUM5QixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3hDLENBQUM7SUFFTyxjQUFjO1FBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSztZQUFFLE1BQU0sS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUE7UUFFbEYsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO1lBQy9DLE1BQU0sS0FBSyxDQUFDLHlGQUF5RixDQUFDLENBQUE7UUFFeEcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO1lBQy9DLE1BQU0sS0FBSyxDQUFDLHlGQUF5RixDQUFDLENBQUE7SUFDMUcsQ0FBQztJQUVPLFVBQVUsQ0FBQyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFpQjtRQUMxRSxNQUFNLGNBQWMsR0FBRyxlQUFlLEVBQUUsWUFBWSxJQUFJLENBQUMsZUFBZSxFQUFFLFdBQVcsQ0FBQTtRQUNyRixNQUFNLGNBQWMsR0FBRyxlQUFlLEVBQUUsWUFBWSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQTtRQUNwRixNQUFNLFdBQVcsR0FBRyxJQUFJLEVBQUUsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQTtRQUUzRCxPQUFPLGNBQWMsSUFBSSxjQUFjLElBQUksV0FBVyxDQUFBO0lBQ3hELENBQUM7SUFFTyxPQUFPLENBQUMsVUFBa0I7UUFDaEMsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFBO1FBQzFCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3RDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUN0QyxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxVQUFVLElBQUksQ0FBQyxHQUFHLFVBQVUsVUFBVSxDQUFDLENBQUE7WUFDekYsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDeEIsQ0FBQzsrR0F0RFUsa0JBQWtCO21HQUFsQixrQkFBa0IsdVJBakJuQjs7Ozs7Ozs7Ozs7Ozs7R0FjVDs7NEZBR1Usa0JBQWtCO2tCQXBCOUIsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsWUFBWTtvQkFDdEIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7R0FjVDtvQkFDRCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtpQkFDaEQ7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBRUcsR0FBRztzQkFBWCxLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBJbnB1dCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcbmltcG9ydCB7IEVjYywgUXJDb2RlIH0gZnJvbSAnLi9xcmNvZGUtZ2VuZXJhdG9yJ1xuXG5jb25zdCBWQUxJRF9DT0xPUl9SRUdFWCA9IC9eIyg/OlswLTlhLWZBLUZdezMsNH0pezEsMn0kL1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdxcmNvZGUtc3ZnJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8c3ZnXG4gICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcbiAgICAgIHZlcnNpb249XCIxLjFcIlxuICAgICAgc3Ryb2tlPVwibm9uZVwiXG4gICAgICBbYXR0ci5hbHRdPVwiYWx0XCJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYXJpYUxhYmVsXCJcbiAgICAgIFthdHRyLndpZHRoXT1cInNpemVcIlxuICAgICAgW2F0dHIuaGVpZ2h0XT1cInNpemVcIlxuICAgICAgW2F0dHIudmlld0JveF09XCJ2aWV3Qm94XCJcbiAgICA+XG4gICAgICA8cmVjdCB3aWR0aD1cIjEwMCVcIiBoZWlnaHQ9XCIxMDAlXCIgW2F0dHIuZmlsbF09XCJiYWNrZ3JvdW5kQ29sb3JcIiAvPlxuICAgICAgPHBhdGggW2F0dHIuZF09XCJkXCIgW2F0dHIuZmlsbF09XCJmb3JlZ3JvdW5kQ29sb3JcIiAvPlxuICAgIDwvc3ZnPlxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBRcmNvZGVTdmdDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBASW5wdXQoKSB2YWx1ZSE6IHN0cmluZ1xuICBASW5wdXQoKSBlY2w6ICdsb3cnIHwgJ21lZGl1bScgfCAncXVhcnRpbGUnIHwgJ2hpZ2gnID0gJ21lZGl1bSdcbiAgQElucHV0KCkgYm9yZGVyU2l6ZSA9IDJcblxuICBASW5wdXQoKSBzaXplOiBzdHJpbmcgfCBudW1iZXIgPSAyNTBcbiAgQElucHV0KCkgYmFja2dyb3VuZENvbG9yID0gJyNGRkZGRkYnXG4gIEBJbnB1dCgpIGZvcmVncm91bmRDb2xvciA9ICcjMDAwMDAwJ1xuXG4gIEBJbnB1dCgpIGFsdDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gIEBJbnB1dCgpIGFyaWFMYWJlbDogc3RyaW5nIHwgdW5kZWZpbmVkXG5cbiAgcHJpdmF0ZSBxciE6IFFyQ29kZVxuXG4gIHZpZXdCb3ghOiBzdHJpbmdcbiAgZCE6IHN0cmluZ1xuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRlSW5wdXRzKClcblxuICAgIGlmICh0aGlzLnNraXBVcGRhdGUoY2hhbmdlcykpIHJldHVyblxuXG4gICAgdGhpcy5xciA9IFFyQ29kZS5lbmNvZGVUZXh0KHRoaXMudmFsdWUsIEVjY1t0aGlzLmVjbF0pXG4gICAgY29uc3QgcyA9IHRoaXMucXIuc2l6ZSArIHRoaXMuYm9yZGVyU2l6ZSAqIDJcbiAgICB0aGlzLnZpZXdCb3ggPSBgMCAwICR7c30gJHtzfWBcbiAgICB0aGlzLmQgPSB0aGlzLmNyZWF0ZUQodGhpcy5ib3JkZXJTaXplKVxuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUlucHV0cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudmFsdWUpIHRocm93IEVycm9yKCdbQGxhcnNjb20vbmctcXJjb2RlLXN2Z10gWW91IG11c3QgcHJvdmlkZSBhIHZhbHVlIScpXG5cbiAgICBpZiAoIVZBTElEX0NPTE9SX1JFR0VYLnRlc3QodGhpcy5iYWNrZ3JvdW5kQ29sb3IpKVxuICAgICAgdGhyb3cgRXJyb3IoJ1tAbGFyc2NvbS9uZy1xcmNvZGUtc3ZnXSBZb3UgbXVzdCBwcm92aWRlIGEgdmFsaWQgYmFja2dyb3VuZENvbG9yIChIRVggUkdCKSBlZzogI0ZGRkZGRicpXG5cbiAgICBpZiAoIVZBTElEX0NPTE9SX1JFR0VYLnRlc3QodGhpcy5mb3JlZ3JvdW5kQ29sb3IpKVxuICAgICAgdGhyb3cgRXJyb3IoJ1tAbGFyc2NvbS9uZy1xcmNvZGUtc3ZnXSBZb3UgbXVzdCBwcm92aWRlIGEgdmFsaWQgZm9yZWdyb3VuZENvbG9yIChIRVggUkdCKSBlZzogIzAwMDAwMCcpXG4gIH1cblxuICBwcml2YXRlIHNraXBVcGRhdGUoeyBiYWNrZ3JvdW5kQ29sb3IsIGZvcmVncm91bmRDb2xvciwgc2l6ZSB9OiBTaW1wbGVDaGFuZ2VzKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYmdDb2xvckNoYW5nZWQgPSBiYWNrZ3JvdW5kQ29sb3I/LmN1cnJlbnRWYWx1ZSAmJiAhYmFja2dyb3VuZENvbG9yPy5maXJzdENoYW5nZVxuICAgIGNvbnN0IGZnQ29sb3JDaGFuZ2VkID0gZm9yZWdyb3VuZENvbG9yPy5jdXJyZW50VmFsdWUgJiYgIWZvcmVncm91bmRDb2xvci5maXJzdENoYW5nZVxuICAgIGNvbnN0IHNpemVDaGFuZ2VkID0gc2l6ZT8uY3VycmVudFZhbHVlICYmICFzaXplLmZpcnN0Q2hhbmdlXG5cbiAgICByZXR1cm4gYmdDb2xvckNoYW5nZWQgfHwgZmdDb2xvckNoYW5nZWQgfHwgc2l6ZUNoYW5nZWRcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRChib3JkZXJTaXplOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdXG4gICAgZm9yIChsZXQgeSA9IDA7IHkgPCB0aGlzLnFyLnNpemU7IHkrKykge1xuICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB0aGlzLnFyLnNpemU7IHgrKykge1xuICAgICAgICBpZiAodGhpcy5xci5nZXRNb2R1bGUoeCwgeSkpIHBhcnRzLnB1c2goYE0ke3ggKyBib3JkZXJTaXplfSwke3kgKyBib3JkZXJTaXplfWgxdjFoLTF6YClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oJyAnKVxuICB9XG59XG4iXX0=