Carousel
July 18, 2025 ยท View on GitHub
An accessible and responsive image carousel component with auto-play functionality, navigation controls, and pagination indicators.
Features
- Auto-play: Automatic slide progression with configurable intervals
- Navigation: Previous/Next buttons for manual control
- Pagination: Dot indicators for direct slide access
- Responsive: Configurable width and height
- Accessible: ARIA labels and keyboard navigation support
- Smooth Transitions: CSS transitions for smooth slide changes
- Touch-friendly: Works on mobile devices
Import
import { Carousel } from '@lib/carousel';
Usage
Basic Example
<Carousel
[images]="[
'https://via.assets.so/game.png?id=1&q=95&w=800&h=300&fit=fill',
'https://via.assets.so/game.png?id=2&q=95&w=800&h=300&fit=fill',
'https://via.assets.so/game.png?id=3&q=95&w=800&h=300&fit=fill'
]"
[width]="800"
[height]="400"
[interval]="5000"
/>
Custom Dimensions
<Carousel
[images]="imageUrls"
[width]="600"
[height]="300"
[interval]="3000"
/>
Component Definition
import { Component } from '@angular/core';
@Component({
selector: 'app-example',
template: `
<Carousel
[images]="carouselImages"
[width]="800"
[height]="400"
[interval]="4000"
/>
`
})
export class ExampleComponent {
carouselImages = [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/image3.jpg',
];
}
API Reference
Props
| Property | Type | Default | Description |
|---|---|---|---|
images | string[] | Required | Array of image URLs to display in the carousel |
width | number | 800 | Width of the carousel in pixels |
height | number | 300 | Height of the carousel in pixels |
interval | number | 4000 | Auto-play interval in milliseconds |
Signals
| Signal | Type | Description |
|---|---|---|
current | signal<number> | Index of the currently displayed slide |
count | computed<number> | Total number of slides |
Methods
| Method | Parameters | Description |
|---|---|---|
next() | None | Navigate to the next slide |
prev() | None | Navigate to the previous slide |
goTo(index) | index: number | Navigate to a specific slide by index |
Accessibility Features
ARIA Support
- Previous Button:
aria-label="Previous Slide" - Next Button:
aria-label="Next Slide" - Images: Automatic
altattributes with slide numbers
Keyboard Navigation
- Arrow Keys: Navigate between slides (when focused)
- Tab Navigation: Focus on navigation buttons and pagination dots
Screen Reader Support
- Descriptive ARIA labels for all interactive elements
- Semantic HTML structure for proper content hierarchy
Examples
Basic Image Carousel
<div class="carousel-container">
<Carousel
[images]="[
'https://via.assets.so/game.png?id=2&q=95&w=800&h=300&fit=fill',
'https://via.assets.so/game.png?id=1&q=95&w=800&h=300&fit=fill',
'https://via.assets.so/game.png?id=3&q=95&w=800&h=300&fit=fill'
]"
[width]="800"
[height]="400"
[interval]="5000"
/>
</div>
Responsive Carousel
<!-- Small carousel for mobile -->
<div class="block md:hidden">
<Carousel
[images]="mobileImages"
[width]="350"
[height]="200"
[interval]="3000"
/>
</div>
<!-- Large carousel for desktop -->
<div class="hidden md:block">
<Carousel
[images]="desktopImages"
[width]="1000"
[height]="500"
[interval]="6000"
/>
</div>
Dynamic Content
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-dynamic-carousel',
template: `
<div class="space-y-4">
<button
(click)="addImage()"
class="px-4 py-2 bg-blue-500 text-white rounded">
Add Image
</button>
<Carousel
[images]="carouselImages()"
[width]="800"
[height]="400"
[interval]="4000"
/>
<p class="text-sm text-gray-600">
Total images: {{ carouselImages().length }}
</p>
</div>
`
})
export class DynamicCarouselComponent {
carouselImages = signal<string[]>([
'https://via.assets.so/game.png?id=1&q=95&w=800&h=400&fit=fill',
'https://via.assets.so/game.png?id=2&q=95&w=800&h=400&fit=fill',
]);
addImage() {
const newId = Math.floor(Math.random() * 100);
const newImage = `https://via.assets.so/game.png?id=${newId}&q=95&w=800&h=400&fit=fill`;
this.carouselImages.update(images => [...images, newImage]);
}
}
Styling
The carousel uses Tailwind CSS classes for styling. You can customize the appearance by modifying the component's template or adding custom CSS.
Default Styles
/* Container */
.carousel-container {
position: relative;
width: 100%;
overflow: hidden;
}
/* Navigation Buttons */
.carousel-nav-button {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: rgba(0, 0, 0, 0.5);
color: white;
border-radius: 50%;
width: 2rem;
height: 2rem;
display: flex;
align-items: center;
justify-content: center;
border: none;
cursor: pointer;
transition: background-color 0.3s ease;
}
.carousel-nav-button:hover {
background: rgba(0, 0, 0, 0.7);
}
/* Pagination Dots */
.carousel-pagination {
position: absolute;
bottom: 1rem;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 0.5rem;
}
.carousel-dot {
width: 0.75rem;
height: 0.75rem;
border-radius: 50%;
background: rgba(255, 255, 255, 0.4);
border: none;
cursor: pointer;
transition: background-color 0.3s ease;
}
.carousel-dot.active {
background: white;
}
Best Practices
Performance
- Optimize Images: Use appropriately sized images for better performance
- Lazy Loading: Consider implementing lazy loading for large image sets
- Preload: Preload the next image for smoother transitions
Accessibility
- Alt Text: Provide meaningful alt text for images when possible
- Reduced Motion: Consider users with motion sensitivity
- Focus Management: Ensure keyboard navigation works properly
UX Guidelines
- Auto-play Control: Allow users to pause auto-play
- Visual Indicators: Always show current slide position
- Touch Support: Ensure touch gestures work on mobile devices
Example Implementation
import { Component, OnDestroy, signal } from '@angular/core';
@Component({
selector: 'app-accessible-carousel',
template: `
<div class="carousel-wrapper" role="region" aria-label="Image carousel">
<Carousel
[images]="accessibleImages()"
[width]="800"
[height]="400"
[interval]="5000"
/>
<!-- Additional accessibility info -->
<div class="sr-only" aria-live="polite">
Slide {{ currentSlideIndex() + 1 }} of {{ totalSlides() }}
</div>
</div>
`
})
export class AccessibleCarouselComponent implements OnDestroy {
accessibleImages = signal([
'https://example.com/product1.jpg',
'https://example.com/product2.jpg',
'https://example.com/product3.jpg',
]);
currentSlideIndex = signal(0);
totalSlides = signal(this.accessibleImages().length);
ngOnDestroy() {
// Cleanup if needed
}
}
Browser Support
The carousel component works in all modern browsers that support:
- CSS Flexbox
- CSS Transforms
- ES6+ JavaScript features
- Angular 17+ signals