Files
ISA-Frontend/libs/shared/barcode
Nino Righi 8b852cbd7a Merged PR 2048: fix(shared-barcode, crm-customer-card): improve barcode rendering with transp...
fix(shared-barcode, crm-customer-card): improve barcode rendering with transparent SVG background

Enhance barcode component flexibility by separating container and SVG
background colors. The SVG barcode now defaults to transparent background
while maintaining container background control, enabling better integration
with various card designs.

Changes:
- Add separate svgBackground input for SVG element (default: transparent)
- Keep background input for container styling (default: #ffffff)
- Add containerWidth and containerHeight inputs for flexible sizing
- Update customer card to remove explicit white background on barcode
- Add opacity styling for inactive customer cards
- Enhance test coverage for new background and sizing inputs

The separation of concerns allows the barcode to adapt to parent container
backgrounds while maintaining consistent rendering across different contexts.

Ref: #5498
2025-11-24 14:58:05 +00:00
..

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