# @isa/ui/carousel

A horizontal scroll container component with left/right navigation arrows, responsive behavior, keyboard support, and auto-hide functionality.

## Features

- ✅ **Smooth horizontal scrolling** with viewport-width scroll amount
- ✅ **Navigation arrows** with auto-hide on hover (configurable)
- ✅ **Keyboard navigation** (Arrow Left/Right when focused)
- ✅ **Responsive design** with native touch gesture support
- ✅ **Disabled states** when at scroll boundaries
- ✅ **Touch gesture support** (native browser behavior)
- ✅ **Content projection** for flexible item rendering
- ✅ **Angular signals** for reactive state management

## Installation

The carousel library is part of the ISA-Frontend monorepo. Import it using the path alias:

```typescript
import { CarouselComponent } from '@isa/ui/carousel';
```

## Basic Usage

```typescript
import { Component } from '@angular/core';
import { CarouselComponent } from '@isa/ui/carousel';

@Component({
  selector: 'app-example',
  template: `
    <ui-carousel>
      @for (item of items; track item.id) {
        <div class="card">{{ item.name }}</div>
      }
    </ui-carousel>
  `,
  imports: [CarouselComponent],
})
export class ExampleComponent {
  items = [
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' },
    { id: 3, name: 'Item 3' },
  ];
}
```

## API Reference

### Component Selector

`ui-carousel`

### Input Properties

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `gap` | `string` | `'1rem'` | CSS gap value for spacing between carousel items (e.g., `'1rem'`, `'2rem'`, `'0.5rem'`). |
| `arrowAutoHide` | `boolean` | `true` | Whether to auto-hide arrows until the carousel is hovered or focused. When `true`, arrows fade in on hover/focus. |

### Methods

| Method | Parameters | Description |
|--------|------------|-------------|
| `scrollToPrevious()` | `event?: Event` | Scrolls to the previous set of items (left). Scrolls by viewport width. |
| `scrollToNext()` | `event?: Event` | Scrolls to the next set of items (right). Scrolls by viewport width. |

### Keyboard Navigation

| Key | Action |
|-----|--------|
| `Arrow Left` | Scroll to previous items |
| `Arrow Right` | Scroll to next items |

**Note:** The carousel must be focused (click or tab to it) for keyboard navigation to work.

## Usage Examples

### Example 1: Basic Carousel

```typescript
import { Component } from '@angular/core';
import { CarouselComponent } from '@isa/ui/carousel';

@Component({
  template: `
    <ui-carousel>
      <div class="card">Card 1</div>
      <div class="card">Card 2</div>
      <div class="card">Card 3</div>
    </ui-carousel>
  `,
  imports: [CarouselComponent],
})
export class BasicCarouselExample {}
```

### Example 2: Always Show Arrows

```typescript
import { Component } from '@angular/core';
import { CarouselComponent } from '@isa/ui/carousel';

@Component({
  template: `
    <ui-carousel [arrowAutoHide]="false">
      @for (product of products; track product.id) {
        <product-card [product]="product"></product-card>
      }
    </ui-carousel>
  `,
  imports: [CarouselComponent],
})
export class AlwaysShowArrowsExample {
  products = [/* ... */];
}
```

### Example 3: Custom Gap

```typescript
import { Component } from '@angular/core';
import { CarouselComponent } from '@isa/ui/carousel';

@Component({
  template: `
    <ui-carousel [gap]="'2rem'">
      @for (card of cards; track card.id) {
        <div class="wide-card">{{ card.content }}</div>
      }
    </ui-carousel>
  `,
  imports: [CarouselComponent],
})
export class CustomGapExample {
  cards = [/* ... */];
}
```

## Styling

### CSS Classes

The carousel component uses the following CSS classes:

| Class | Element | Description |
|-------|---------|-------------|
| `.ui-carousel` | Host element | Main container with focus styles |
| `.ui-carousel--auto-hide` | Host element | Applied when `arrowAutoHide` is `true` |
| `.ui-carousel__wrapper` | Wrapper | Contains buttons and scroll container |
| `.ui-carousel__container` | Scroll container | Horizontal scroll area with hidden scrollbar |
| `.ui-carousel__button` | Navigation button | Left/right arrow buttons |
| `.ui-carousel__button--left` | Left button | Positioned on the left side |
| `.ui-carousel__button--right` | Right button | Positioned on the right side |

### Custom Styling

You can override the default styles using CSS:

```scss
// Custom arrow button colors
.ui-carousel__button {
  background-color: #your-color;
  border-color: #your-border-color;
  color: #your-icon-color;

  &:hover {
    background-color: #your-hover-color;
  }
}

// Custom focus outline
.ui-carousel:focus {
  outline-color: #your-focus-color;
}

// Custom scroll container
.ui-carousel__container {
  // Add custom styles
}
```

## Accessibility

### Keyboard Navigation

- The carousel is focusable with `tabindex="0"`
- Arrow Left/Right keys scroll the carousel when focused
- Focus outline visible for keyboard users (`:focus-visible`)

### ARIA Attributes

- Navigation buttons have `aria-label` attributes:
  - Left button: `"Previous"`
  - Right button: `"Next"`
- Buttons are properly marked with `type="button"` to prevent form submission

### E2E Testing Attributes

All interactive elements include proper data attributes for automated testing:

```html
<button data-what="button" data-which="carousel-previous">...</button>
<button data-what="button" data-which="carousel-next">...</button>
```

## Behavior

### Scroll Logic

- **Scroll Amount**: Scrolls by the viewport width of the container
- **Smooth Scrolling**: Uses CSS `scroll-behavior: smooth` for animated transitions
- **Boundary Detection**: Automatically disables arrows when at the start/end of content
- **Responsive**: Arrows always show when content is scrollable, on all screen sizes

### Auto-Hide Arrows

When `arrowAutoHide` is `true`:

- Arrows are invisible by default (`opacity: 0`)
- Arrows fade in on carousel hover or focus
- Smooth CSS transitions for fade effects

### Touch Gestures

The carousel supports native touch gestures on mobile/tablet devices:

- Swipe left/right to scroll
- No custom JavaScript needed (browser default behavior)

## Browser Compatibility

- Modern browsers with CSS Grid and Flexbox support
- Native smooth scrolling support
- ResizeObserver API for content change detection

## Performance

- **OnPush Change Detection**: Optimized for minimal re-renders
- **Angular Signals**: Fine-grained reactivity with automatic dependency tracking
- **Native Scroll**: Leverages browser's native scroll performance
- **Cleanup**: Automatic event listener and observer cleanup on destroy

## Testing

Run unit tests:

```bash
npx nx test ui-carousel --skip-nx-cache
```

The carousel component includes comprehensive tests for:

- Component creation and default values
- Input property changes
- CSS class application
- Content projection
- Keyboard navigation
- Navigation button rendering
- E2E data attributes

## Related Components

- `@isa/ui/buttons` - Button components used for navigation arrows
- `@isa/icons` - Icon library for arrow icons

## Contributing

When contributing to this component:

1. Follow the ISA-Frontend coding conventions
2. Use Angular signals for reactive state
3. Include E2E data attributes (`data-what`, `data-which`)
4. Write comprehensive Vitest tests
5. Update this README for API changes

## License

Internal ISA-Frontend library.
