# @isa/ui/item-rows

A collection of reusable row components for displaying structured data with consistent layouts across Angular applications.

## Overview

The Item Rows UI library provides three specialized row components for presenting structured information in a consistent, accessible format. These components enable standardized display of product items, client information, and key-value data pairs throughout the ISA application. Each component uses content projection and directive-based composition for maximum flexibility while maintaining design system consistency.

## Table of Contents

- [Features](#features)
- [Quick Start](#quick-start)
- [Core Concepts](#core-concepts)
- [API Reference](#api-reference)
- [Usage Examples](#usage-examples)
- [Styling and Customization](#styling-and-customization)
- [Testing](#testing)
- [Architecture Notes](#architecture-notes)

## Features

- **Three row components** - ItemRowComponent, ItemRowDataComponent, and ClientRowComponent
- **Directive-based composition** - Flexible data organization with semantic directives
- **Content projection** - Full control over row content via ng-content
- **Convenience imports** - Pre-bundled directive arrays for easy imports
- **OnPush change detection** - Optimized rendering performance
- **ViewEncapsulation.None** - Global styling integration with design system
- **BEM-like CSS naming** - Predictable class structure for styling
- **Standalone architecture** - Modern Angular components with explicit imports
- **Type-safe directives** - Directive selectors support both attribute and element syntax
- **SCSS integration** - Component-scoped styles with BEM conventions

## Quick Start

### 1. Basic Item Row

```typescript
import { Component } from '@angular/core';
import { ItemRowComponent } from '@isa/ui/item-rows';

@Component({
  selector: 'app-product-list-item',
  template: `
    <ui-item-row>
      <h3>Product Name</h3>
      <p>Product description and details</p>
    </ui-item-row>
  `,
  imports: [ItemRowComponent]
})
export class ProductListItemComponent {}
```

### 2. Item Row with Data Pairs

```typescript
import { Component } from '@angular/core';
import { ItemRowDataImports } from '@isa/ui/item-rows';

@Component({
  selector: 'app-product-details',
  template: `
    <ui-item-row-data>
      <div uiItemRowDataRow>
        <span uiItemRowDataLabel>Price:</span>
        <span uiItemRowDataValue>$29.99</span>
      </div>
      <div uiItemRowDataRow>
        <span uiItemRowDataLabel>Stock:</span>
        <span uiItemRowDataValue>In Stock</span>
      </div>
    </ui-item-row-data>
  `,
  imports: [ItemRowDataImports]
})
export class ProductDetailsComponent {}
```

### 3. Client Row

```typescript
import { Component } from '@angular/core';
import { ClientRowImports } from '@isa/ui/item-rows';

@Component({
  selector: 'app-customer-card',
  template: `
    <ui-client-row>
      <div uiClientRowContent>
        <h4>Customer Name</h4>
        <p>customer@example.com</p>
      </div>
    </ui-client-row>
  `,
  imports: [ClientRowImports]
})
export class CustomerCardComponent {}
```

## Core Concepts

### Component Types

The library provides three distinct row components, each optimized for specific use cases:

#### 1. ItemRowComponent
- **Purpose**: General-purpose row container for any item content
- **Use Cases**: Product listings, order items, search results, general lists
- **Structure**: Simple container with no internal layout structure
- **CSS Class**: `ui-item-row`
- **Selectors**: `<ui-item-row>` or `[ui-item-row]`

#### 2. ItemRowDataComponent with Directives
- **Purpose**: Key-value data presentation with label/value pairs
- **Use Cases**: Product specifications, order details, metadata display
- **Structure**: Hierarchical with row/label/value organization
- **CSS Classes**:
  - `ui-item-row-data` (container)
  - `ui-item-row-data-row` (individual row)
  - `ui-item-row-data-label` (left-side label)
  - `ui-item-row-data-value` (right-side value)
- **Directives**:
  - `ItemRowDataComponent` - Main container
  - `ItemRowDataRowDirective` - Individual data row
  - `ItemRowDataLabelDirective` - Label element
  - `ItemRowDataValueDirective` - Value element

#### 3. ClientRowComponent
- **Purpose**: Customer/client information display
- **Use Cases**: Customer lists, client cards, user profiles
- **Structure**: Specialized layout for client-specific content
- **CSS Classes**:
  - `ui-client-row` (container)
  - `ui-client-row-content` (content wrapper)
- **Directives**:
  - `ClientRowComponent` - Main container
  - `ClientRowContentDirective` - Content wrapper

### Directive-Based Composition

The library uses directives to create semantic, reusable layout patterns:

```typescript
// Attribute syntax (preferred)
<div uiItemRowDataRow>
  <span uiItemRowDataLabel>Label</span>
  <span uiItemRowDataValue>Value</span>
</div>

// Element syntax (alternative)
<ui-item-row-data-row>
  <ui-item-row-data-label>Label</ui-item-row-data-label>
  <ui-item-row-data-value>Value</ui-item-row-data-value>
</ui-item-row-data-row>
```

**Benefits of directive composition**:
- **Semantic HTML** - Clear intent in templates
- **Flexible markup** - Use with any HTML element
- **Type safety** - Directive selectors enforce correct usage
- **Consistent styling** - Predictable CSS classes

### Convenience Import Arrays

The library provides pre-bundled directive arrays for simplified imports:

```typescript
// ItemRowDataImports - All data row components and directives
export const ItemRowDataImports = [
  ItemRowDataComponent,
  ItemRowDataLabelDirective,
  ItemRowDataValueDirective,
  ItemRowDataRowDirective,
];

// ClientRowImports - Client row component and content directive
export const ClientRowImports = [
  ClientRowComponent,
  ClientRowContentDirective
];
```

**Usage:**
```typescript
@Component({
  // Import entire directive family at once
  imports: [ItemRowDataImports]
})
```

## API Reference

### ItemRowComponent

Basic row container for general item display.

#### Selector
```html
<ui-item-row>Content</ui-item-row>
<!-- OR -->
<div ui-item-row>Content</div>
```

#### Properties
- **No inputs** - Pure container component
- **Host class**: `ui-item-row`
- **Change Detection**: OnPush
- **Encapsulation**: None

#### Template
```html
<ng-content></ng-content>
```

#### Example
```html
<ui-item-row>
  <div class="product-header">
    <h3>Product Title</h3>
    <span class="price">$99.99</span>
  </div>
  <p class="description">Product description text</p>
</ui-item-row>
```

### ItemRowDataComponent

Container for key-value data pairs with semantic directives.

#### Selector
```html
<ui-item-row-data>Content</ui-item-row-data>
```

#### Properties
- **No inputs** - Container with directive-based children
- **Host class**: `ui-item-row-data`
- **Change Detection**: OnPush
- **Encapsulation**: None

#### Template
```html
<ng-content></ng-content>
```

#### Example
```html
<ui-item-row-data>
  <div uiItemRowDataRow>
    <span uiItemRowDataLabel>SKU:</span>
    <span uiItemRowDataValue>ABC-12345</span>
  </div>
</ui-item-row-data>
```

### ItemRowDataRowDirective

Marks an element as a data row within ItemRowDataComponent.

#### Selectors
```html
<div uiItemRowDataRow>Content</div>
<!-- OR -->
<ui-item-row-data-row>Content</ui-item-row-data-row>
```

#### Properties
- **No inputs** - Structural directive
- **Host class**: `ui-item-row-data-row`

#### Example
```html
<div uiItemRowDataRow>
  <span uiItemRowDataLabel>Weight:</span>
  <span uiItemRowDataValue>2.5 kg</span>
</div>
```

### ItemRowDataLabelDirective

Marks an element as a label (left side) in a data row.

#### Selectors
```html
<span uiItemRowDataLabel>Label Text</span>
<!-- OR -->
<ui-item-row-data-label>Label Text</ui-item-row-data-label>
```

#### Properties
- **No inputs** - Structural directive
- **Host class**: `ui-item-row-data-label`

#### Example
```html
<span uiItemRowDataLabel>Category:</span>
```

### ItemRowDataValueDirective

Marks an element as a value (right side) in a data row.

#### Selectors
```html
<span uiItemRowDataValue>Value Text</span>
<!-- OR -->
<ui-item-row-data-value>Value Text</ui-item-row-data-value>
```

#### Properties
- **No inputs** - Structural directive
- **Host class**: `ui-item-row-data-value`

#### Example
```html
<span uiItemRowDataValue>Electronics</span>
```

### ClientRowComponent

Specialized row component for client/customer information.

#### Selector
```html
<ui-client-row>Content</ui-client-row>
```

#### Properties
- **No inputs** - Container component
- **Host class**: `ui-client-row`
- **Change Detection**: OnPush
- **Encapsulation**: None
- **Standalone**: true

#### Template
```html
<ng-content></ng-content>
```

#### Example
```html
<ui-client-row>
  <div uiClientRowContent>
    <h4>John Doe</h4>
    <p>john.doe@example.com</p>
  </div>
</ui-client-row>
```

### ClientRowContentDirective

Marks an element as content within ClientRowComponent.

#### Selectors
```html
<div uiClientRowContent>Content</div>
<!-- OR -->
<ui-client-row-content>Content</ui-client-row-content>
```

#### Properties
- **No inputs** - Structural directive
- **Host class**: `ui-client-row-content`

#### Example
```html
<div uiClientRowContent>
  <div class="client-info">
    <span class="client-name">Jane Smith</span>
    <span class="client-id">#12345</span>
  </div>
</div>
```

### Convenience Import Arrays

#### ItemRowDataImports
Bundle of all data row components and directives.

```typescript
export const ItemRowDataImports = [
  ItemRowDataComponent,
  ItemRowDataLabelDirective,
  ItemRowDataValueDirective,
  ItemRowDataRowDirective,
];
```

**Usage:**
```typescript
@Component({
  imports: [ItemRowDataImports]
})
```

#### ClientRowImports
Bundle of client row component and directive.

```typescript
export const ClientRowImports = [
  ClientRowComponent,
  ClientRowContentDirective
];
```

**Usage:**
```typescript
@Component({
  imports: [ClientRowImports]
})
```

## Usage Examples

### Product Information Display

```typescript
import { Component, input } from '@angular/core';
import { ItemRowComponent, ItemRowDataImports } from '@isa/ui/item-rows';

interface Product {
  id: number;
  name: string;
  sku: string;
  price: number;
  stock: number;
  category: string;
}

@Component({
  selector: 'app-product-info',
  template: `
    <ui-item-row>
      <h3>{{ product().name }}</h3>

      <ui-item-row-data>
        <div uiItemRowDataRow>
          <span uiItemRowDataLabel>SKU:</span>
          <span uiItemRowDataValue>{{ product().sku }}</span>
        </div>

        <div uiItemRowDataRow>
          <span uiItemRowDataLabel>Price:</span>
          <span uiItemRowDataValue>\${{ product().price }}</span>
        </div>

        <div uiItemRowDataRow>
          <span uiItemRowDataLabel>Stock:</span>
          <span uiItemRowDataValue>{{ product().stock }} units</span>
        </div>

        <div uiItemRowDataRow>
          <span uiItemRowDataLabel>Category:</span>
          <span uiItemRowDataValue>{{ product().category }}</span>
        </div>
      </ui-item-row-data>
    </ui-item-row>
  `,
  imports: [ItemRowComponent, ItemRowDataImports]
})
export class ProductInfoComponent {
  product = input.required<Product>();
}
```

### Order Details List

```typescript
import { Component, input } from '@angular/core';
import { ItemRowDataImports } from '@isa/ui/item-rows';
import { DatePipe, CurrencyPipe } from '@angular/common';

interface Order {
  orderNumber: string;
  date: Date;
  status: string;
  total: number;
  shippingMethod: string;
}

@Component({
  selector: 'app-order-details',
  template: `
    <ui-item-row-data>
      <div uiItemRowDataRow>
        <span uiItemRowDataLabel>Order Number:</span>
        <strong uiItemRowDataValue>{{ order().orderNumber }}</strong>
      </div>

      <div uiItemRowDataRow>
        <span uiItemRowDataLabel>Order Date:</span>
        <span uiItemRowDataValue>{{ order().date | date:'short' }}</span>
      </div>

      <div uiItemRowDataRow>
        <span uiItemRowDataLabel>Status:</span>
        <span uiItemRowDataValue class="status-{{ order().status }}">
          {{ order().status }}
        </span>
      </div>

      <div uiItemRowDataRow>
        <span uiItemRowDataLabel>Total:</span>
        <span uiItemRowDataValue>{{ order().total | currency }}</span>
      </div>

      <div uiItemRowDataRow>
        <span uiItemRowDataLabel>Shipping:</span>
        <span uiItemRowDataValue>{{ order().shippingMethod }}</span>
      </div>
    </ui-item-row-data>
  `,
  imports: [ItemRowDataImports, DatePipe, CurrencyPipe]
})
export class OrderDetailsComponent {
  order = input.required<Order>();
}
```

### Customer List with Client Rows

```typescript
import { Component, signal } from '@angular/core';
import { ClientRowImports } from '@isa/ui/item-rows';

interface Customer {
  id: number;
  name: string;
  email: string;
  phone: string;
  company: string;
}

@Component({
  selector: 'app-customer-list',
  template: `
    <div class="customer-list">
      @for (customer of customers(); track customer.id) {
        <ui-client-row>
          <div uiClientRowContent class="customer-card">
            <div class="customer-header">
              <h4>{{ customer.name }}</h4>
              <span class="customer-id">#{{ customer.id }}</span>
            </div>
            <div class="customer-details">
              <p>{{ customer.email }}</p>
              <p>{{ customer.phone }}</p>
              <p class="company">{{ customer.company }}</p>
            </div>
          </div>
        </ui-client-row>
      }
    </div>
  `,
  imports: [ClientRowImports],
  styles: [`
    .customer-list {
      display: flex;
      flex-direction: column;
      gap: 1rem;
    }

    .customer-card {
      padding: 1rem;
    }

    .customer-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 0.5rem;
    }

    .company {
      color: var(--isa-text-secondary);
      font-size: 0.875rem;
    }
  `]
})
export class CustomerListComponent {
  customers = signal<Customer[]>([
    {
      id: 1,
      name: 'John Doe',
      email: 'john@example.com',
      phone: '+1 555-0100',
      company: 'Acme Corp'
    },
    // ... more customers
  ]);
}
```

### Mixed Content with Conditional Rendering

```typescript
import { Component, input, computed } from '@angular/core';
import { ItemRowComponent, ItemRowDataImports } from '@isa/ui/item-rows';

interface ProductWithVariants {
  name: string;
  basePrice: number;
  hasVariants: boolean;
  variants?: Array<{ name: string; price: number }>;
  specifications: Record<string, string>;
}

@Component({
  selector: 'app-product-variant-info',
  template: `
    <ui-item-row>
      <h3>{{ product().name }}</h3>

      @if (product().hasVariants) {
        <div class="variants">
          @for (variant of product().variants; track variant.name) {
            <span class="variant-chip">
              {{ variant.name }} - \${{ variant.price }}
            </span>
          }
        </div>
      }

      <ui-item-row-data>
        @for (spec of specificationEntries(); track spec.key) {
          <div uiItemRowDataRow>
            <span uiItemRowDataLabel>{{ spec.key }}:</span>
            <span uiItemRowDataValue>{{ spec.value }}</span>
          </div>
        }
      </ui-item-row-data>
    </ui-item-row>
  `,
  imports: [ItemRowComponent, ItemRowDataImports]
})
export class ProductVariantInfoComponent {
  product = input.required<ProductWithVariants>();

  specificationEntries = computed(() =>
    Object.entries(this.product().specifications).map(([key, value]) => ({
      key,
      value
    }))
  );
}
```

### Nested Row Structures

```typescript
import { Component } from '@angular/core';
import { ItemRowComponent, ItemRowDataImports } from '@isa/ui/item-rows';

@Component({
  selector: 'app-order-item-detail',
  template: `
    <ui-item-row class="order-item">
      <!-- Product header -->
      <div class="item-header">
        <h4>Wireless Headphones</h4>
        <span class="quantity">Qty: 2</span>
      </div>

      <!-- Primary product details -->
      <ui-item-row-data class="primary-details">
        <div uiItemRowDataRow>
          <span uiItemRowDataLabel>Unit Price:</span>
          <span uiItemRowDataValue>$79.99</span>
        </div>

        <div uiItemRowDataRow>
          <span uiItemRowDataLabel>Subtotal:</span>
          <span uiItemRowDataValue>$159.98</span>
        </div>
      </ui-item-row-data>

      <!-- Shipping information -->
      <ui-item-row-data class="shipping-details">
        <div uiItemRowDataRow>
          <span uiItemRowDataLabel>Estimated Delivery:</span>
          <span uiItemRowDataValue>Dec 25, 2025</span>
        </div>

        <div uiItemRowDataRow>
          <span uiItemRowDataLabel>Shipping Method:</span>
          <span uiItemRowDataValue>Standard (3-5 days)</span>
        </div>
      </ui-item-row-data>
    </ui-item-row>
  `,
  imports: [ItemRowComponent, ItemRowDataImports]
})
export class OrderItemDetailComponent {}
```

### Dynamic Data Rows

```typescript
import { Component, input, computed } from '@angular/core';
import { ItemRowDataImports } from '@isa/ui/item-rows';

@Component({
  selector: 'app-dynamic-metadata',
  template: `
    <ui-item-row-data>
      @for (field of metadataFields(); track field.key) {
        <div uiItemRowDataRow>
          <span uiItemRowDataLabel>{{ field.label }}:</span>
          <span
            uiItemRowDataValue
            [class]="field.highlightClass">
            {{ field.value }}
          </span>
        </div>
      }
    </ui-item-row-data>
  `,
  imports: [ItemRowDataImports]
})
export class DynamicMetadataComponent {
  metadata = input.required<Record<string, any>>();

  metadataFields = computed(() => {
    const data = this.metadata();
    return Object.entries(data).map(([key, value]) => ({
      key,
      label: this.formatLabel(key),
      value: this.formatValue(value),
      highlightClass: this.getHighlightClass(key, value)
    }));
  });

  private formatLabel(key: string): string {
    return key
      .replace(/([A-Z])/g, ' $1')
      .replace(/^./, str => str.toUpperCase());
  }

  private formatValue(value: any): string {
    if (typeof value === 'boolean') return value ? 'Yes' : 'No';
    if (value === null || value === undefined) return 'N/A';
    return String(value);
  }

  private getHighlightClass(key: string, value: any): string {
    if (key === 'status') {
      return value === 'active' ? 'text-success' : 'text-muted';
    }
    return '';
  }
}
```

## Styling and Customization

### CSS Class Structure

The components generate predictable BEM-like class structures:

```css
/* ItemRowComponent */
.ui-item-row {
  /* Base item row styles */
  display: block;
  padding: 1rem;
  border-bottom: 1px solid var(--isa-border-color);
}

/* ItemRowDataComponent */
.ui-item-row-data {
  /* Container for data rows */
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.ui-item-row-data-row {
  /* Individual data row */
  display: grid;
  grid-template-columns: minmax(120px, 1fr) 2fr;
  gap: 1rem;
  align-items: start;
}

.ui-item-row-data-label {
  /* Label (left column) */
  font-weight: 500;
  color: var(--isa-text-secondary);
  text-align: left;
}

.ui-item-row-data-value {
  /* Value (right column) */
  color: var(--isa-text-primary);
  text-align: left;
}

/* ClientRowComponent */
.ui-client-row {
  /* Client row container */
  display: block;
  background-color: var(--isa-surface);
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.ui-client-row-content {
  /* Client row content wrapper */
  padding: 1.5rem;
}
```

### Custom Styling Examples

```scss
// Custom product row styling
.product-listing {
  ui-item-row {
    background-color: white;
    border-radius: 4px;
    margin-bottom: 1rem;
    transition: box-shadow 0.2s;

    &:hover {
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    }
  }

  .ui-item-row-data {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--isa-border-color);
  }

  .ui-item-row-data-label {
    font-size: 0.875rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }

  .ui-item-row-data-value {
    font-weight: 600;
  }
}

// Custom client row styling
.customer-directory {
  ui-client-row {
    margin-bottom: 1rem;
    border: 1px solid var(--isa-border-light);

    &:hover {
      border-color: var(--isa-brand-primary);
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }
  }

  .ui-client-row-content {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 1rem;
    align-items: center;
  }
}
```

### Responsive Layouts

```css
/* Mobile-first responsive data rows */
.ui-item-row-data-row {
  /* Stack on mobile */
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

@media (min-width: 640px) {
  .ui-item-row-data-row {
    /* Side-by-side on tablet and up */
    flex-direction: row;
    justify-content: space-between;
  }
}

@media (min-width: 1024px) {
  .ui-item-row-data-row {
    /* Grid layout on desktop */
    display: grid;
    grid-template-columns: minmax(150px, 1fr) 3fr;
  }
}
```

### Tailwind CSS Integration

```html
<!-- Using Tailwind classes with item rows -->
<ui-item-row class="p-4 mb-4 bg-white rounded-lg shadow-sm hover:shadow-md transition-shadow">
  <ui-item-row-data class="space-y-2">
    <div uiItemRowDataRow class="grid grid-cols-2 gap-4">
      <span uiItemRowDataLabel class="text-sm font-medium text-gray-600">
        Label
      </span>
      <span uiItemRowDataValue class="text-base text-gray-900">
        Value
      </span>
    </div>
  </ui-item-row-data>
</ui-item-row>
```

## Testing

The library uses **Jest** for testing (legacy setup - migration to Vitest pending).

### Running Tests

```bash
# Run tests for this library
npx nx test ui-item-rows --skip-nx-cache

# Run tests with coverage
npx nx test ui-item-rows --code-coverage --skip-nx-cache

# Run tests in watch mode
npx nx test ui-item-rows --watch
```

### Test Structure

The library should include tests covering:

- **Component rendering** - Verify components render correctly
- **Content projection** - Test ng-content works as expected
- **Directive application** - Verify CSS classes are applied correctly
- **Host bindings** - Test host class bindings
- **Nested structures** - Test complex nesting scenarios

### Example Test

```typescript
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { describe, it, expect, beforeEach } from '@jest/globals';
import {
  ItemRowDataComponent,
  ItemRowDataRowDirective,
  ItemRowDataLabelDirective,
  ItemRowDataValueDirective
} from './item-row-data.component';

describe('ItemRowDataComponent', () => {
  let component: ItemRowDataComponent;
  let fixture: ComponentFixture<ItemRowDataComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        ItemRowDataComponent,
        ItemRowDataRowDirective,
        ItemRowDataLabelDirective,
        ItemRowDataValueDirective
      ]
    });
    fixture = TestBed.createComponent(ItemRowDataComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should have ui-item-row-data class', () => {
    const element = fixture.nativeElement as HTMLElement;
    expect(element.classList.contains('ui-item-row-data')).toBe(true);
  });

  it('should project content', () => {
    const compiled = fixture.nativeElement as HTMLElement;
    const testContent = '<div>Test Content</div>';
    compiled.innerHTML = testContent;
    fixture.detectChanges();
    expect(compiled.innerHTML).toContain('Test Content');
  });
});
```

## Architecture Notes

### Current Architecture

The library follows a directive-based composition pattern:

```
ItemRowComponent (Simple Container)
├── No inputs, pure content projection
└── CSS: ui-item-row

ItemRowDataComponent (Data Container)
├── No inputs, container for data rows
├── CSS: ui-item-row-data
└── Works with directives:
    ├── ItemRowDataRowDirective (row wrapper)
    ├── ItemRowDataLabelDirective (label/key)
    └── ItemRowDataValueDirective (value)

ClientRowComponent (Client Container)
├── No inputs, specialized for clients
├── CSS: ui-client-row
└── Works with directive:
    └── ClientRowContentDirective (content wrapper)
```

### Design Decisions

#### 1. Directive-Based Composition

**Decision**: Use directives instead of child components for layout structure
**Rationale**:
- Flexibility to use any HTML element (div, span, p, etc.)
- Semantic selectors (`uiItemRowDataLabel` vs generic component)
- Lighter weight than full components
- Easier to apply to existing markup

**Impact**: More flexible templates with clear semantic meaning

#### 2. Dual Selector Support

**Decision**: Support both attribute and element selectors
**Rationale**:
- `[uiItemRowDataRow]` - Attribute syntax for flexible element types
- `<ui-item-row-data-row>` - Element syntax for clarity
- Developers can choose based on preference and context
- Consistent with Angular best practices

**Impact**: Better developer experience with choice of syntax

#### 3. Convenience Import Arrays

**Decision**: Export pre-bundled directive arrays
**Rationale**:
- Reduces boilerplate in component imports
- Ensures all related directives are imported together
- Clear API - import array, not individual directives
- Prevents missing directive errors

**Impact**: Simpler, more maintainable component declarations

#### 4. No Component Inputs

**Decision**: Components have no @Input properties
**Rationale**:
- Pure structural components focused on layout
- Content and styling controlled via projection and CSS
- Simpler API with fewer configuration options
- Promotes composition over configuration

**Impact**: Simpler components, styling handled via CSS

#### 5. ViewEncapsulation.None

**Decision**: Use ViewEncapsulation.None for global CSS classes
**Rationale**:
- Consistent with ISA design system approach
- BEM-like naming prevents conflicts
- Easier theming and customization
- Works well with Tailwind utility classes

**Impact**: Flexible styling with global CSS classes

### Migration Considerations

#### Testing Framework Migration (Pending)

**Current State**: Uses Jest
**Target**: Migrate to Vitest + Angular Testing Utilities
**Reason**: Aligns with ISA codebase standards (13 libraries already migrated)
**Priority**: Low - works well with Jest currently

**Migration steps when ready**:
1. Update project.json to use @nx/vite:test
2. Add vite.config.mts
3. Convert tests to use Vitest imports
4. Update test setup files

### Performance Considerations

1. **OnPush change detection** - Minimal overhead for structural components
2. **No reactive inputs** - No signal overhead
3. **Simple templates** - Just ng-content projection
4. **Directive overhead** - Minimal, just CSS class application
5. **No JavaScript logic** - Pure presentational components

### Future Enhancements

Potential improvements identified:

1. **Icon Support** - Add optional icon directives for labels
2. **Accordion Behavior** - Collapsible row variants
3. **Selection Support** - Checkbox/radio integration
4. **Loading States** - Skeleton variants for data rows
5. **Empty States** - Placeholder content when no data
6. **Accessibility** - ARIA attributes for screen readers
7. **Animation Support** - Entry/exit animations for rows

## Dependencies

### Required Libraries

- `@angular/core` - Angular framework (20.1.2)
- `@angular/common` - CommonModule (implicitly used)

### Optional Libraries

None - pure presentation components with no external dependencies.

### Path Alias

Import from: `@isa/ui/item-rows`

## License

Internal ISA Frontend library - not for external distribution.
