feat(shared,crm): add Code 128 barcode generation library Implements new @isa/shared/barcode library with directive and component for generating Code 128 barcodes using JsBarcode. Features: - Standalone Angular directive (svg[sharedBarcode]) - Standalone Angular component (<shared-barcode>) - Signal-based reactive inputs - SVG-based vector rendering - Customizable colors, size, margins, fonts - Comprehensive Vitest test coverage (39 tests) - Storybook stories for both directive and component - Integrated into customer loyalty card component Changes: - Created @isa/shared/barcode library with directive and component - Added JsBarcode dependency (v3.12.1) - Integrated barcode into customer loyalty card display - Added Storybook stories for interactive documentation - Fixed ui-switch story component reference - Updated library reference documentation Refs #5496 Related work items: #5496
7.6 KiB
@isa/shared/barcode
Angular library for generating Code 128 barcodes using JsBarcode.
Provides both a component (easier to use) and a directive (more flexible) for rendering barcodes.
Features
- ✅ Standalone Angular component & directive
- ✅ Code 128 barcode format support
- ✅ Signal-based reactive inputs
- ✅ SVG-based rendering (vector graphics)
- ✅ Highly customizable (colors, size, margins, fonts)
- ✅ Automatic re-rendering on input changes
- ✅ Built-in logging with
@isa/core/logging - ✅ Comprehensive Vitest test coverage
Installation
Component (Recommended)
The component provides the easiest way to add barcodes:
import { BarcodeComponent } from '@isa/shared/barcode';
@Component({
selector: 'app-my-component',
standalone: true,
imports: [BarcodeComponent],
template: `
<shared-barcode [value]="productEan" />
`,
})
export class MyComponent {
productEan = '9783161484100';
}
Directive (Advanced)
Use the directive when you need to apply the barcode to an existing SVG element:
import { BarcodeDirective } from '@isa/shared/barcode';
@Component({
selector: 'app-my-component',
standalone: true,
imports: [BarcodeDirective],
template: `
<svg sharedBarcode [value]="productEan"></svg>
`,
})
export class MyComponent {
productEan = '9783161484100';
}
Basic Usage
Component - Minimal Example
<shared-barcode [value]="'123456789'" />
Directive - Minimal Example
<svg sharedBarcode [value]="'123456789'"></svg>
Component - With Custom Options
<shared-barcode
[value]="barcodeValue"
[width]="3"
[height]="150"
[displayValue]="true"
[lineColor]="'#000000'"
[background]="'#ffffff'"
/>
Directive - With Custom Options
<svg
sharedBarcode
[value]="barcodeValue"
[width]="3"
[height]="150"
[displayValue]="true"
[lineColor]="'#000000'"
[background]="'#ffffff'"
></svg>
TypeScript Example
import { Component, signal } from '@angular/core';
import { BarcodeComponent } from '@isa/shared/barcode';
@Component({
selector: 'app-product-label',
standalone: true,
imports: [BarcodeComponent],
template: `
<div class="label">
<h3>Product Label</h3>
<shared-barcode
[value]="ean()"
[width]="2"
[height]="100"
[displayValue]="true"
/>
</div>
`,
})
export class ProductLabelComponent {
ean = signal('4006381333634');
}
API Reference
Inputs
| Input | Type | Default | Description |
|---|---|---|---|
value |
string |
(required) | The barcode value to encode |
format |
string |
'CODE128' |
Barcode format (supports CODE128, CODE39, EAN13, etc.) |
width |
number |
2 |
Width of a single bar in pixels |
height |
number |
100 |
Height of the barcode in pixels |
displayValue |
boolean |
true |
Whether to display the human-readable text below the barcode |
lineColor |
string |
'#000000' |
Color of the barcode bars and text |
background |
string |
'#ffffff' |
Background color |
fontSize |
number |
20 |
Font size for the human-readable text |
margin |
number |
10 |
Margin around the barcode in pixels |
Selector
selector: 'svg[sharedBarcode]'
The directive must be applied to an <svg> element.
Examples
Component Examples
Large Barcode
<shared-barcode
[value]="'9876543210'"
[width]="4"
[height]="200"
[fontSize]="28"
/>
Compact Barcode (No Text)
<shared-barcode
[value]="'123456'"
[width]="1"
[height]="60"
[displayValue]="false"
[margin]="5"
/>
Colored Barcode
<shared-barcode
[value]="'PRODUCT001'"
[lineColor]="'#0066CC'"
[background]="'#F0F0F0'"
/>
Directive Examples
Large Barcode
<svg
sharedBarcode
[value]="'9876543210'"
[width]="4"
[height]="200"
[fontSize]="28"
></svg>
Compact Barcode (No Text)
<svg
sharedBarcode
[value]="'123456'"
[width]="1"
[height]="60"
[displayValue]="false"
[margin]="5"
></svg>
Colored Barcode
<svg
sharedBarcode
[value]="'PRODUCT001'"
[lineColor]="'#0066CC'"
[background]="'#F0F0F0'"
></svg>
Reactive Value Updates
@Component({
selector: 'app-barcode-scanner',
standalone: true,
imports: [BarcodeDirective],
template: `
<input [(ngModel)]="scannedValue" placeholder="Scan barcode..." />
<svg sharedBarcode [value]="scannedValue"></svg>
`,
})
export class BarcodeScannerComponent {
scannedValue = '';
}
The barcode automatically re-renders when the value changes.
Multiple Barcodes
@Component({
selector: 'app-product-list',
standalone: true,
imports: [BarcodeDirective, CommonModule],
template: `
@for (product of products; track product.id) {
<div class="product-card">
<h4>{{ product.name }}</h4>
<svg
sharedBarcode
[value]="product.ean"
[width]="2"
[height]="80"
></svg>
</div>
}
`,
})
export class ProductListComponent {
products = [
{ id: 1, name: 'Product A', ean: '1234567890123' },
{ id: 2, name: 'Product B', ean: '9876543210987' },
];
}
Styling
The directive renders an SVG element. You can apply CSS styles to the parent SVG element:
svg[sharedBarcode] {
border: 1px solid #ccc;
padding: 8px;
border-radius: 4px;
background: white;
}
Error Handling
The directive includes built-in error handling:
- Invalid values: Logged as warnings (check browser console with logging enabled)
- Empty values: Handled gracefully without crashing
- Rendering errors: Caught and logged with
@isa/core/logging
Testing
The library uses Vitest with Angular Testing Utilities for testing.
Running Tests
# Run tests
npx nx test shared-barcode
# Run tests with coverage
npx nx test shared-barcode --coverage.enabled=true
# Skip cache for fresh test run
npx nx test shared-barcode --skip-nx-cache
Test Reports
- JUnit XML:
testresults/junit-shared-barcode.xml - Cobertura Coverage:
coverage/libs/shared/barcode/cobertura-coverage.xml
Example Test
import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BarcodeDirective } from '@isa/shared/barcode';
@Component({
standalone: true,
imports: [BarcodeDirective],
template: '<svg sharedBarcode [value]="value"></svg>',
})
class TestComponent {
value = '123456789';
}
describe('BarcodeDirective', () => {
let fixture: ComponentFixture<TestComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TestComponent],
}).compileComponents();
fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
});
it('should render barcode', () => {
const svg = fixture.nativeElement.querySelector('svg');
expect(svg).toBeTruthy();
});
});
Browser Support
Supports all modern browsers with SVG rendering capabilities:
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
Dependencies
- JsBarcode:
^3.12.1- Core barcode generation library - @types/jsbarcode: TypeScript type definitions
Related Libraries
@isa/shared/scanner: Barcode scanning functionality@isa/shared/product-image: Product image display with CDN support
License
Internal ISA-Frontend library. Not for external distribution.
Support
For issues or feature requests, consult the ISA-Frontend development team.