ng-hero-carousel
Introduction
ng-hero-carousel is a standalone, reusable and customizable component for Angular 18, 19 and 20.
It is designed to work with signals and Angular zoneless, providing a lightweight, flexible, and accessible her section carousel. It is also fully compatible with SSR, CSR and prerender.
Installation
If you want to install the latest version (currently 20):
npm install ng-hero-carousel
Angular 19:
npm install ng-hero-carousel@v19-lts
Angular 18:
npm install ng-hero-carousel@v18-lts
Overview
Using ng-hero-carousel is easy:
- The only required input for ng-hero-carousel is [slides] where you can add backgrounds and some predefined content for each slide.
- Configure its style, behavior, and accessibility using inputs..
- Style it with customizable CSS variables to match your design needs.
Here’s a basic usage example:
import { NgHeroCarousel, HeroCarouselItem } from 'ng-hero-carousel';
@Component({
imports: [NgHeroCarousel],
template: `
<ng-hero-carousel
[slides]="slidesObject()"
/>
`
})
class App {
slidesObject = signal<HeroCarouselItem[]>([
{
image_url: 'img1.jpg',
title: 'First Slide',
subtitle: '1st slide subtitle'
},
{
image_url: 'img2.jpg',
title: 'Second Slide',
subtitle: '2nd slide subtitle'
}
]);
}
Functionality
slides must be an array of objects with the type HeroCarouselItem[]. You can import this type directly from the library:
import { HeroCarouselItem } from 'ng-hero-carousel';
NgHeroCarousel Interface
Here is the exact declaration of the CarouselItem type:
export interface HeroCarouselItem {
image_url?: string;
backgroundColor?: string;
title?: string;
subtitle?: string;
};
| Property | Description | Type | Required |
|---|---|---|---|
| image_url | Image URL for the slide | string | No |
| backgroundColor | Background color or gradient for the slide, if needed | string | No |
| title | Responsive title for the slide (<h2>) | string | No |
| subtitle | Responsive subtitle for the slide (<h3>) | string | No |
💡 It´s important to know that you don´t have to add all elements. If you want, for exaple, only background and a title in one slide, you can set just image_url and title.
Adding custom content: slide for
You can add the custom content you want into any slide you decide. For doing that you must use ng-template and the SlideForDirective.
Here you have a simple example to add a button in the first slide:
import { NgHeroCarousel, CarouselItem, SlideForDirective } from 'ng-hero-carousel';
@Component({
imports: [NgHeroCarousel, SlideForDirective],
template: `
<ng-hero-carousel
[slides]="items()"
>
<ng-template [slideFor]="0">
<button>
Button in first slide
</button>
</ng-template>
</ng-hero-carousel>
`
})
class App {
items = signal<CarouselItem[]>([
{ image_url: 'img1.jpg', title: 'First Slide', subtitle: '1st slide subtitle' },
{ image_url: 'img2.jpg', title: 'Second Slide', subtitle: '2nd slide subtitle' },
]);
}
As you can see in the example above, to add content to a slide you just need to use ng-template and the [slideFor] directive, which receives the number of slide you want to add custom content.
Adding custom content: outerContent
You can also add content that remains visible across all slides. It will be visible even if you navigate through slides. Example of use: imagine that the carousel is opened into a modal window. You can easily add a "close button" this way.
import { NgHeroCarousel, CarouselItem } from 'ng-hero-carousel';
@Component({
imports: [NgHeroCarousel],
template: `
<ng-hero-carousel
[slides]="items()"
>
<ng-template #outerContent>
<button style="position: absolute; top: 1rem; right: 1.5rem;">
X
</button>
</ng-template>
</ng-hero-carousel>
`
})
class App {
items = signal<CarouselItem[]>([
{ image_url: 'img1.jpg', title: 'First Slide', subtitle: '1st slide subtitle' },
{ image_url: 'img2.jpg', title: 'Second Slide', subtitle: '2nd slide subtitle' },
]);
}
As you can see in the example above, you just have to add <ng-template #outerContent> and use the template reference #outerContent. IMPORTANT: You must set the content inside <ng-template #outerContent> and place it where you want.
Inputs and Outputs
There are several inputs/outputs that allow you to customize ng-hero-carousel component.
Here is an example:
<ng-hero-carousel
[slides]="items()"
[hasOverlay]="true"
[transitionTime]="800"
arrowsPlacement="auto"
[hasCounter]="true"
indicators="bars"
[hasAutoplay]="true"
[autoplayTime]="4000"
[autoplayResumeTime]="15000"
(selected)="selectedItem.set($event)"
lang="en"
accessibilityOptions="accOps()"
>
Style & Behavior Inputs
| Input | Description | Default |
|---|---|---|
| [hasOverlay] | Add an overlay on top of the background image. | true |
| [transitionTime] | Time in ms of the transition between slides | 800 |
| arrowsPlacement | Position of arrows (Auto: up for desktop, down for mobile) | 'auto' |
| [hasCounter] | Add a counter (Ex: 1/5). | false |
| indicators | Select the type of indicator for the slides | 'bars' |
Autoplay inputs
| Input | Description | Default |
|---|---|---|
| [hasAutoplay] | Select whether you want autoplay or not | true |
| [autoplayTime] | Time in ms in which the slide is automatically changed | 7000 |
| [autoplayResumeTime] | Time in ms to resume autoplay when it stops (e.g. clicking on a slide) | 15000 |
Current/selected slide output
You can use (selected) output to get the current slide on screen. For example, if you want to build your own counter.
Accessibility Inputs
| Input | Description | Default |
|---|---|---|
| lang | Select the language for accessibility | 'en' |
| customAria | Set up your own custom aria attributes (more info below) | null |
Styling
You can easily customize the component’s appearance using the CSS variables listed below.
ng-hero-carousel{
--carousel-bg: red;
--carousel-overlay-opacity: 0.8;
--carousel-accent-color: red;
}
| Variable | Description | Default |
|---|---|---|
| --carousel-width | Component width | 100% |
| --carousel-height | Component height | 100dvh |
| --carousel-bg | General background. Inherits from parent by default | inherit |
| --carousel-overlay-color | [hasOverlay] Custom color for the overlay | black |
| --carousel-overlay-opacity | Custom opacity for the overlay | .5 |
| --carousel-title-size | Font size for slide titles | 1.8rem |
| --carousel-subtitle-size | Font size for slide subtitles | 1.2rem |
| --carousel-transition-translate-y | TranslateY for slide content entrance/exit | -2rem |
| --carousel-text-color | Text color for titles and subtitles | inherit |
| --carousel-accent-color | Base accent color for arrows, indicators, autoplay button | currentColor |
| --carousel-autoplay-color | Custom color for the autoplay toggle button | var(--carousel-accent-color) |
| --carousel-arrow-color | Custom color for arrow buttons | var(--carousel-accent-color) |
| --carousel-indicator-color | Custom color for slide indicators | var(--carousel-accent-color) |
| --carousel-autoplay-top | Top position for the autoplay toggle button | 0rem |
| --carousel-autoplay-left | Left position for the autoplay toggle button | 0rem |
| --carousel-counter-top | Top position for the counter if enabled | 0rem |
| --carousel-counter-right | Right position for the counter if enabled | 0rem |
Accessibility
There are two ways of setting the aria-label attributes: by lang attribute or by customAria attribute (See Accessibility Inputs at Inputs and Outputs section)
If needed, you can import HeroCarouselLangs and HeroCarouselCustomAria types like this:
import { HeroCarouselLangs, HeroCarouselCustomAria } from 'ng-hero-carousel';
'lang' attribute:
The component includes five predefined languages for accessibility labels that you can set easily with the lang attribute:
Laguages can be: english (en), spanish (es), italian (it), french (fr) or deutch (de)
*** We recommend using the lang attribute if you don't need any other languages than the ones provided by default. It's simple and compliant with WAI-ARIA standards. ***
<ng-hero-carousel lang="es" />
💡 If no value is provided in lang, the default language is English (en).
💡 If your application supports multiple languages, you can bind the lang attribute to a signal and link it with a select, for example.
'customAria' attribute:
In addition to the predefined languages available through the lang attribute, you can fully customize the ARIA labels for your menu button by using the customAria input.
This option gives you full control over the text announced by screen readers when the menu is opened or closed — perfect for custom translations, accessibility improvements, or when you want to use a language that is not included in the predefined set.
Here is the exact declaration of the HeroCarouselCustomAria type:
export interface HeroCarouselCustomAria {
hostAriaLabel?: string;
autoplayPauseLabel?: string;
autoplayPlayLabel?: string;
prevBtnAriaLabel?: string;
nextBtnAriaLabel?: string;
slidesRegionAriaLabel?: string;
slidesRegionRoleDescription?: string;
slideAriaLabel?: (currentSlide: number, total: number) => string;
slideRoleDescription?: string;
};
| Property | Description |
|---|---|
| hostAriaLabel | aria-label for the host component. Useful to indicate the user that has entered into a carousel |
| autoplayPauseLabel | aria-label for autoplay button when autoplay is playing (described action is to pause it) |
| autoplayPlayLabel | aria-label for autoplay button when autoplay is paused (described action is to resume it) |
| prevBtnAriaLabel | aria-label for the arrow button that goes to prev slide |
| nextBtnAriaLabel | aria-label for the arrow button that goes to next slide |
| slidesRegionAriaLabel | aria-label for the container of all slides |
| slidesRegionRoleDescription | aria-roledescription for the container of all slides (role is 'group') |
| slideAriaLabel | aria-label for each slide. Is a function that returns the text for each slide (see example below) |
| slideRoleDescription | aria-roledescription for individual slide (role is 'group') |
Example of usage:
import { NgHeroCarousel, HeroCarouselItem, HeroCarouselCustomAria } from 'ng-hero-carousel';
@Component({
imports: [NgHeroCarousel],
template: `
<ng-hero-carousel
[slides]="items()"
[customAria]="accOpts()"
/>
`
})
class App {
items = signal<HeroCarouselItem[]>([
{ image_url: 'img1.jpg', title: 'First Slide', subtitle: '1st slide subtitle' },
{ image_url: 'img2.jpg', title: 'Second Slide', subtitle: '2nd slide subtitle' },
]);
accOpts = signal<HeroCarouselCustomAria>({
hostAriaLabel: 'Main carousel CHANGED',
autoplayPauseLabel: 'Pause carousel autoplay CHANGED',
autoplayPlayLabel: 'Resume carousel autoplay CHANGED',
prevBtnAriaLabel: 'Go to previous slide CHANGED',
nextBtnAriaLabel: 'Go to next slide CHANGED',
slidesRegionAriaLabel: 'Wide carousel CHANGED',
slidesRegionRoleDescription: 'Carousel CHANGED',
slideAriaLabel: (currentSlide: number, total: number) =>
'CHANGED - Slide ' + currentSlide + 'of ' + total
slideRoleDescription: 'CHANGED - slide',
});
}
💡 Remember that what is indicated in the customAria attribute replaces the default language set in lang.
💡 If you only set one of the properties, the other will use the label from the current lang.