Files
ISA-Frontend/libs/shared/barcode/README.md
Lorenz Hilpert 7a6a2dc49d Merged PR 2038: feat(shared,crm): add Code 128 barcode generation library
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
2025-11-21 13:42:32 +00:00

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

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
  • @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.