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