mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
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
377 lines
7.6 KiB
Markdown
377 lines
7.6 KiB
Markdown
# @isa/shared/barcode
|
|
|
|
Angular library for generating Code 128 barcodes using [JsBarcode](https://github.com/lindell/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:
|
|
|
|
```typescript
|
|
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:
|
|
|
|
```typescript
|
|
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
|
|
|
|
```html
|
|
<shared-barcode [value]="'123456789'" />
|
|
```
|
|
|
|
### Directive - Minimal Example
|
|
|
|
```html
|
|
<svg sharedBarcode [value]="'123456789'"></svg>
|
|
```
|
|
|
|
### Component - With Custom Options
|
|
|
|
```html
|
|
<shared-barcode
|
|
[value]="barcodeValue"
|
|
[width]="3"
|
|
[height]="150"
|
|
[displayValue]="true"
|
|
[lineColor]="'#000000'"
|
|
[background]="'#ffffff'"
|
|
/>
|
|
```
|
|
|
|
### Directive - With Custom Options
|
|
|
|
```html
|
|
<svg
|
|
sharedBarcode
|
|
[value]="barcodeValue"
|
|
[width]="3"
|
|
[height]="150"
|
|
[displayValue]="true"
|
|
[lineColor]="'#000000'"
|
|
[background]="'#ffffff'"
|
|
></svg>
|
|
```
|
|
|
|
### TypeScript Example
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
selector: 'svg[sharedBarcode]'
|
|
```
|
|
|
|
The directive must be applied to an `<svg>` element.
|
|
|
|
## Examples
|
|
|
|
### Component Examples
|
|
|
|
#### Large Barcode
|
|
|
|
```html
|
|
<shared-barcode
|
|
[value]="'9876543210'"
|
|
[width]="4"
|
|
[height]="200"
|
|
[fontSize]="28"
|
|
/>
|
|
```
|
|
|
|
#### Compact Barcode (No Text)
|
|
|
|
```html
|
|
<shared-barcode
|
|
[value]="'123456'"
|
|
[width]="1"
|
|
[height]="60"
|
|
[displayValue]="false"
|
|
[margin]="5"
|
|
/>
|
|
```
|
|
|
|
#### Colored Barcode
|
|
|
|
```html
|
|
<shared-barcode
|
|
[value]="'PRODUCT001'"
|
|
[lineColor]="'#0066CC'"
|
|
[background]="'#F0F0F0'"
|
|
/>
|
|
```
|
|
|
|
### Directive Examples
|
|
|
|
#### Large Barcode
|
|
|
|
```html
|
|
<svg
|
|
sharedBarcode
|
|
[value]="'9876543210'"
|
|
[width]="4"
|
|
[height]="200"
|
|
[fontSize]="28"
|
|
></svg>
|
|
```
|
|
|
|
#### Compact Barcode (No Text)
|
|
|
|
```html
|
|
<svg
|
|
sharedBarcode
|
|
[value]="'123456'"
|
|
[width]="1"
|
|
[height]="60"
|
|
[displayValue]="false"
|
|
[margin]="5"
|
|
></svg>
|
|
```
|
|
|
|
#### Colored Barcode
|
|
|
|
```html
|
|
<svg
|
|
sharedBarcode
|
|
[value]="'PRODUCT001'"
|
|
[lineColor]="'#0066CC'"
|
|
[background]="'#F0F0F0'"
|
|
></svg>
|
|
```
|
|
|
|
### Reactive Value Updates
|
|
|
|
```typescript
|
|
@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
|
|
|
|
```typescript
|
|
@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:
|
|
|
|
```css
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```typescript
|
|
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.
|