An open API service indexing awesome lists of open source software.

https://github.com/donaldxdonald/embla-carousel-angular

Angular wrapper for Embla Carousel, a lightweight carousel library with fluid motion and great swipe precision.
https://github.com/donaldxdonald/embla-carousel-angular

angular carousel embla-carousel slider swiper

Last synced: 3 days ago
JSON representation

Angular wrapper for Embla Carousel, a lightweight carousel library with fluid motion and great swipe precision.

Awesome Lists containing this project

README

          


Embla Carousel

Angular


NPM version
Bundlephobia minzip
NPM downloads

Embla Carousel Angular


An Angular wrapper for Embla Carousel.


Installation

```shell
npm i embla-carousel-angular
```


The component structure

Embla Carousel provides the handy `EmblaCarouselDirective` **standalone** directive for seamless integration with Angular. A minimal setup requires an **overflow wrapper** and a **scroll container**. Start by adding the following structure to your carousel:

```ts
import { Component, effect, viewChild } from '@angular/core'
import {
EmblaCarouselDirective,
EmblaCarouselType
} from 'embla-carousel-angular'

@Component({
selector: 'app-carousel',
template: `



Slide 1

Slide 2

Slide 3



`,
imports: [EmblaCarouselDirective],
standalone: true
})
export class CarouselComponent implements AfterViewInit {
private emblaRef = viewChild(EmblaCarouselDirective);

private emblaApi?: EmblaCarouselType
private options = { loop: false }

constructor() {
effect(() => {
this.emblaApi = this.emblaRef()?.emblaApi;
});
}
}
```

Styling the carousel

The element with the classname `embla` is needed to cover the scroll overflow. Its child element with the `container` classname is the scroll body that scrolls the slides. Continue by adding the following **CSS** to these elements:

```css
.embla {
overflow: hidden;
}
.embla__container {
display: flex;
}
.embla__slide {
flex: 0 0 100%;
min-width: 0;
}
```

Accessing the carousel API

The `emblaCarousel` directive takes the Embla Carousel [options](https://www.embla-carousel.com/api/options/) as part of its inputs. Additionally, you can access the [API](https://www.embla-carousel.com/api/) by using the `viewChild` signal to access the carousel in the effect.

> [!WARNING]
> Calling the following embla APIs directly will trigger too much ChangeDetection, which will lead to serious performance issues.


- `emblaApi.on()`
- `emblaApi.scrollNext()`
- `emblaApi.scrollPrev()`
- `emblaApi.scrollTo()`

Consider using the following methods which are wrapped with `ngZone.runOutsideAngular()`:

- `EmblaCarouselDirective.scrollPrev()`
- `EmblaCarouselDirective.scrollNext()`
- `EmblaCarouselDirective.scrollTo()`

```ts
import { Component, effect, viewChild } from '@angular/core'
import {
EmblaCarouselDirective,
EmblaCarouselType
} from 'embla-carousel-angular'

@Component({
selector: 'app-carousel',
template: `



Slide 1

Slide 2

Slide 3



`,
imports: [EmblaCarouselDirective],
standalone: true
})
export class CarouselComponent {
private emblaRef = viewChild(EmblaCarouselDirective);

private emblaApi?: EmblaCarouselType
private options = { loop: false }

constructor() {
effect(() => {
this.emblaApi = this.emblaRef()?.emblaApi;
});
}
}
```

Listening the carousel events

The `emblaCarousel` directive also provides a custom event: `emblaChange` that forwards embla events, also wrapped in `ngZone.runOutsideAngular`. You need to listen by passing the specified event names into `subscribeToEvents` input on demand.

```ts
import { Component, effect, viewChild } from '@angular/core'
import {
EmblaCarouselDirective,
EmblaCarouselType,
EmblaEventType
} from 'embla-carousel-angular'

@Component({
selector: 'app-carousel',
template: `



Slide 1

Slide 2

Slide 3



`,
imports: [EmblaCarouselDirective],
standalone: true
})
export class CarouselComponent {
private emblaRef = viewChild(EmblaCarouselDirective);

private emblaApi?: EmblaCarouselType
private options = { loop: false }

constructor() {
effect(() => {
this.emblaApi = this.emblaRef()?.emblaApi;
});
}

public readonly subscribeToEvents: EmblaEventType[] = [
'init',
'pointerDown',
'pointerUp',
'slidesChanged',
'slidesInView',
'select',
'settle',
'destroy',
'reInit',
'resize',
'scroll'
]

onEmblaChanged(event: EmblaEventType): void {
console.log(`Embla event triggered: ${event}`)
}
}
```

Adding plugins

Start by installing the plugin you want to use. In this example, we're going to install the [Autoplay](https://www.embla-carousel.com/plugins/autoplay/) plugin:

```shell
npm install embla-carousel-autoplay --save
```

The `emblaCarousel` directive inputs also accepts [plugins](https://www.embla-carousel.com/plugins/). Note that plugins need to be passed in an array like so:

```ts
import { Component, effect, viewChild } from '@angular/core'
import {
EmblaCarouselDirective,
EmblaCarouselType
} from 'embla-carousel-angular'
import Autoplay from 'embla-carousel-autoplay'

@Component({
selector: 'app-carousel',
template: `



Slide 1

Slide 2

Slide 3



`,
imports: [EmblaCarouselDirective],
standalone: true
})
export class CarouselComponent {
private emblaRef = viewChild(EmblaCarouselDirective);

private emblaApi?: EmblaCarouselType
public options = { loop: false }
public plugins = [Autoplay()]

constructor() {
effect(() => {
this.emblaApi = this.emblaRef()?.emblaApi;
});
}
}
```



Thanks




Thanks to davidjerleke, zip-fa and JeanMeche for the review and advice.