npm package: @fylgja/snap-slider
Description: A CSS-powered slider/carousel, enhanced with JavaScript for improved functionality and accessibility
Author: Fylgja
Latest version: 2.1.0

# Fylgja - Snap Slider

[![NPM version](https://img.shields.io/npm/v/@fylgja/snap-slider?logo=npm)](https://www.npmjs.com/package/@fylgja/snap-slider)
[![License](https://img.shields.io/github/license/fylgja/snap-slider?color=%23234)](/LICENSE)
[![Netlify Status](https://api.netlify.com/api/v1/badges/1a127f61-d12b-46cf-858f-65a1350323e7/deploy-status)](https://fylgja-snap-slider.netlify.app/)

A CSS-powered slider/carousel, enhanced with JavaScript for improved functionality and accessibility.

The Snap Slider is available as a Custom Element (the primary and recommended way) or as an AlpineJS component.

- **Custom Element Live Demo:** [https://fylgja-snap-slider.netlify.app/](https://fylgja-snap-slider.netlify.app/)
- **AlpineJS Live Demo:** [https://fylgja-snap-slider.netlify.app/alpinejs](https://fylgja-snap-slider.netlify.app/alpinejs)

## Installation

The Snap Slider can be integrated into your project via NPM or by using a CDN.

### NPM Installation

Install the package from NPM:

```sh
npm install @fylgja/snap-slider
```

### CDN Integration

Alternatively, you can include the script directly in your HTML using a `<script>` tag.

**For the Custom Element:**

```html
<script defer src="https://unpkg.com/@fylgja/snap-slider/dist/custom-element/cdn.min.js"></script>
```

**For the AlpineJS version:**

```html
<script defer src="https://unpkg.com/@fylgja/snap-slider/dist/alpine/cdn.min.js"></script>
```

## Usage

The Snap Slider can be used as a Custom Element or as an AlpineJS component.

### Custom Element (Recommended)

Import the custom element into your project:

```js
import '@fylgja/snap-slider/custom-element';
```

Then, use the `<snap-slider>` element in your HTML. A `[data-track]` child element is required to contain the slides.

```html
<snap-slider>
    <div data-track>
        <!-- Your slides go here -->
    </div>
</snap-slider>
```

### AlpineJS Component

To use the AlpineJS version, import the component and register it with Alpine:

```js
import Alpine from 'alpinejs';
import snapSlider from '@fylgja/snap-slider/alpine';

window.Alpine = Alpine;

Alpine.plugin(snapSlider);
Alpine.start();
```

Then, apply the `x-snap-slider` directive to your slider element.

```html
<div x-data x-snap-slider>
    <div data-track>
        <!-- Your slides go here -->
    </div>
</div>
```

## Configuration

The `snap-slider` supports the following data attributes for configuration:

| Data Attribute                | Description                                                                | Default       |
| ----------------------------- | -------------------------------------------------------------------------- | ------------- |
| `data-track`                  | **Required.** Identifies the container for the slider's slides.            |               |
| `data-next`                   | Designates a button to navigate to the next slide.                         |               |
| `data-prev`                   | Designates a button to navigate to the previous slide.                     |               |
| `data-pager`                  | Designates the container for pagination markers.                           |               |
| `data-auto-pager`             | Automatically generates pagination markers.                                | `false`       |
| `data-group-pager`            | Groups pager markers based on the number of visible slides.                | `false`       |
| `data-slide-label-sepparator` | Customizes the separator in the `aria-label` for slides (e.g., "1 of 12"). | `of`          |
| `data-pager-class`            | Sets custom classes for the pager container.                               | `snap-pager`  |
| `data-marker-class`           | Sets custom classes for the pager markers.                                 | `snap-marker` |

### AlpineJS Configuration

For the AlpineJS version, boolean options like `auto-pager` and `group-pager` are passed as modifiers to the `x-snap-slider` directive:

```html
<div x-data x-snap-slider.auto-pager.group-pager>
    ...
</div>
```

Other data attributes can be applied directly to the element as usual.

### Pager

You can add a pager to your slider in two ways:

#### 1. Auto Pager

The easiest way to add a pager is by using the `data-auto-pager` attribute (or `x-snap-slider.auto-pager` for AlpineJS). This will automatically generate a pager for you.

By default, the pager is inserted after the `[data-track]` element. You can customize its location by adding an empty `[data-pager]` container anywhere inside the slider element.

#### 2. Custom Pager

For more control, you can create a custom pager. Each slide must have a unique ID, and each pager marker must link to a slide's ID using `href="#slide-id"` or `data-target-id="slide-id"`.

### Group Pager

When multiple slides are visible at once, you can use the `data-group-pager` attribute (or `x-snap-slider.group-pager` for AlpineJS) to group the pager markers. This will only show one marker for each visible group of slides.

## JavaScript API

You can interact with the slider programmatically using the following methods and events.

### Methods

First, get the `SnapSlider` instance:

**For the Custom Element:**
```js
const snapSliderElement = document.querySelector('snap-slider');
const snapSliderInstance = snapSliderElement.slider;
```

**For the AlpineJS component:**

```js
const sliderEl = document.querySelector('[x-snap-slider]');
const snapSliderInstance = sliderEl.snapSlider;
```

| Method            | Description                                                                     |
| ----------------- | ------------------------------------------------------------------------------- |
| `init()`          | Initializes the slider. This is called automatically.                           |
| `destroy()`       | Removes all event listeners and observers.                                      |
| `refreshSlides()` | Re-initializes the slider, useful when slides are added or removed dynamically. |

### Events

The slider dispatches a `slideChange` event on the slider element whenever the in-view slides change.

```js
const sliderEl = document.querySelector('snap-slider'); // Or '[x-snap-slider]'
sliderEl.addEventListener('slideChange', (event) => {
    console.log(event.detail);
});
```

The `event.detail` object contains the following properties:

| Property            | Description                                             |
| ------------------- | ------------------------------------------------------- |
| `inViewSlides`      | An array of the slides currently in view.               |
| `totalInViewSlides` | The total number of slides in view.                     |
| `firstInViewSlide`  | The first slide in view.                                |
| `lastInViewSlide`   | The last slide in view.                                 |
| `isAtStart`         | A boolean indicating if the slider is at the beginning. |
| `isAtEnd`           | A boolean indicating if the slider is at the end.       |
| `hasNoOverflow`     | A boolean indicating if all slides are visible at once. |