# Carousel

The **Carousel** widget, also known as an image slider or slideshow, is a popular UI component used to display a series of items (images, content cards, or custom widgets) in a horizontal or vertical scrollable format. Users can swipe through slides manually or let them auto-play.

Carousels are perfect for showcasing featured content, product galleries, onboarding screens, testimonials, or promotional banners within limited screen space.

{% embed url="<https://www.youtube.com/watch?v=FM9luXU-O0E>" %}

Watch this on Youtube: <https://www.youtube.com/watch?v=FM9luXU-O0E>

{% hint style="info" %}
Our Carousel widget works like Flutter's `carousel_slider` package, providing smooth transitions, auto-play capabilities, and extensive customization options for creating engaging content sliders.
{% endhint %}

{% hint style="success" %}
**User Experience Tip:** Carousels are most effective when they have 3-7 slides. Too many slides can overwhelm users, while too few may not justify the carousel format.
{% endhint %}

***

### Core Concepts

#### 1. Dynamic Children Only

The Carousel widget **requires** a data source to function. You provide a `JsonArray` of data, and Carousel automatically creates a slide for each item in the array. Each slide uses a single child widget template that you design.

This is the same pattern as ListView and GridView—Carousel is built for data-driven content.

#### 2. Viewport Fractions & Multi-Item Display

Unlike a full-screen slider, Carousel can show multiple items at once:

* **Viewport Fraction** controls how much of the viewport each slide occupies.
* A value of `1.0` means each slide fills the entire width (single item view).
* A value of `0.8` means each slide takes 80% of the width, showing portions of adjacent slides.

This "peek" effect helps users understand there's more content to explore.

#### 3. Center Page Enlargement

For added visual emphasis, you can enlarge the center (active) slide while keeping adjacent slides at normal size:

* Enable `Enlarge Center Page` to activate this effect.
* Use `Enlarge Factor` to control how much bigger the center slide appears.
* Creates a 3D-like "focus" effect that draws attention to the active slide.

***

### Data Source Property

The **Data Source** is required for the Carousel to function. It determines what slides will be displayed.

#### How to Configure the Data Source

1. In the properties panel, locate the **`Data Source`** field.
2. You can provide data in two ways:

**Option 1: Static JsonArray**

Enter a fixed JSON array directly:

```json
[
  {"image": "https://example.com/image1.jpg", "title": "Slide 1", "description": "First slide"},
  {"image": "https://example.com/image2.jpg", "title": "Slide 2", "description": "Second slide"},
  {"image": "https://example.com/image3.jpg", "title": "Slide 3", "description": "Third slide"}
]
```

This is useful for prototyping or displaying a fixed set of slides.

**Option 2: Dynamic Expression**

Bind the data source to an expression that returns a `JsonArray`:

* **From an API Response:** `${apiResponse.data.banners}`
* **From App State:** `${appState.featuredProducts}`
* **From a Variable:** `${carouselItems}`

The Carousel will automatically update whenever the data source changes.

#### Accessing Item Data with `currentItem`

Inside the child template, you have access to special variables:

* **`currentItem`**: The data for the current slide being rendered.
  * For objects: `${currentItem.image}`, `${currentItem.title}`
  * For simple values: `${currentItem}`
* **`index`**: The zero-based index of the current slide.

{% hint style="warning" %}
**Important:** The Data Source must be a `JsonArray`. If you bind it to a non-array value, the Carousel will not render any slides.
{% endhint %}

***

### Properties

#### Layout & Sizing

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td><code>Height</code></td><td>The fixed height of the carousel container. Controls how tall the carousel appears on the screen.</td></tr><tr><td><code>Width</code></td><td>The fixed width of the carousel container. If not set, it will expand to fill available width.</td></tr><tr><td><code>Aspect Ratio</code></td><td>The aspect ratio of each slide (width:height). For example, <code>16:9</code> for widescreen, <code>1:1</code> for square, <code>4:3</code> for standard.</td></tr></tbody></table>

{% hint style="warning" %}
**Important:** When a fixed `Height` is provided, the `Aspect Ratio` property has no effect. The carousel will use the specified height directly. To use aspect ratio for responsive sizing, leave the `Height` property empty or unset.
{% endhint %}

#### Scrolling Behavior

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td><code>Direction</code></td><td>The scroll direction of the carousel. Can be <code>Horizontal</code> (default) or <code>Vertical</code>.</td></tr><tr><td><code>Initial Page</code></td><td>The zero-based index of the slide to show initially. For example, <code>0</code> shows the first slide, <code>1</code> shows the second slide.</td></tr><tr><td><code>Page Snapping</code></td><td>If <code>true</code>, the carousel snaps to the nearest slide when scrolling stops. Default is <code>true</code>.</td></tr><tr><td><code>Infinite Scroll</code></td><td>If <code>true</code>, the carousel loops continuously—after the last slide, it goes back to the first. Default is <code>true</code>.</td></tr><tr><td><code>Reverse Scroll</code></td><td>If <code>true</code>, the carousel scrolls in the opposite direction.</td></tr></tbody></table>

#### Viewport & Visual Effects

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td><code>Viewport Fraction</code></td><td>The fraction of the viewport that each slide occupies. Values between <code>0</code> and <code>1</code>. <code>1.0</code> = full width, <code>0.8</code> = 80% width (shows peek of adjacent slides). Default is <code>0.8</code>.</td></tr><tr><td><code>Pad Ends</code></td><td>If <code>true</code>, adds padding to the first and last slides so they can be centered properly.</td></tr><tr><td><code>Enlarge Center Page</code></td><td>If <code>true</code>, the center (active) slide will be larger than adjacent slides, creating a focus effect.</td></tr><tr><td><code>Enlarge Factor</code></td><td>When <code>Enlarge Center Page</code> is enabled, this controls how much bigger the center slide appears. Values between <code>0</code> and <code>1</code>. Default is <code>0.3</code> (30% larger).</td></tr><tr><td><code>Keep Alive</code></td><td>If <code>true</code>, the state of each slide is preserved as it scrolls off-screen. Useful for maintaining form inputs or scroll positions within slides.</td></tr></tbody></table>

#### Auto-Play Settings

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td><code>Auto Play</code></td><td>If <code>true</code>, the carousel automatically advances to the next slide at regular intervals.</td></tr><tr><td><code>Auto Play Interval (ms)</code></td><td>The delay (in milliseconds) between auto-play transitions. For example, <code>3000</code> = 3 seconds between slides. Default is <code>4000</code>.</td></tr><tr><td><code>Animation Duration (ms)</code></td><td>The duration (in milliseconds) of the slide transition animation. For example, <code>800</code> = 0.8 seconds to slide to the next item. Default is <code>300</code>.</td></tr></tbody></table>

{% hint style="info" %}
**Auto-Play Best Practice:** Use auto-play sparingly and ensure the interval is long enough for users to read the content. Always provide manual controls (navigation dots or arrows) so users can pause or navigate manually.
{% endhint %}

***

### Page Indicator Properties

The page indicator (dots) shows users which slide is currently active and how many total slides exist.

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td><code>Show Indicator</code></td><td>If <code>true</code>, displays page indicator dots below the carousel.</td></tr><tr><td><code>Indicator Offset</code></td><td>The vertical offset (in pixels) of the indicator from the bottom of the carousel. Positive values move it up, negative values move it down.</td></tr><tr><td><code>Dot Width</code></td><td>The width of each indicator dot in pixels.</td></tr><tr><td><code>Dot Height</code></td><td>The height of each indicator dot in pixels.</td></tr><tr><td><code>Spacing</code></td><td>The horizontal spacing between indicator dots in pixels.</td></tr><tr><td><code>Dot Color</code></td><td>The color of inactive (non-active) indicator dots in HEX format.</td></tr><tr><td><code>Active Dot Color</code></td><td>The color of the active indicator dot in HEX format.</td></tr><tr><td><code>Indicator Effect</code></td><td>The animation effect for the indicator transition. Options may include <code>Worm</code>, <code>Expanding</code>, <code>Jumping</code>, <code>Slide</code>, etc.</td></tr></tbody></table>

***

### Event Handlers

The Carousel widget supports an event handler that triggers when the active slide changes:

#### On Changed

This event is triggered whenever the user swipes to a new slide or when auto-play advances to the next slide. The event provides the `index` of the newly active slide.

**Available Data:**

* **`index`**: The zero-based index of the slide that just became active. You can use this value in your actions to track which slide is currently displayed.

**Use Cases:**

* Update a custom page counter (e.g., "Slide 2 of 5")
* Track analytics for which slides users view
* Load related content based on the active slide index
* Update app state with the current slide position
* Trigger animations or effects when specific slides are reached

**How to Use:**

1. Select the Carousel widget.
2. Navigate to **Event Handlers** in the properties panel.
3. Find **On Changed** and click **+ Add Action**.
4. Add your desired action (e.g., Set State, Call API, Show Toast).
5. Use `${index}` in your action to access the new slide index.

**Example:** Set a state variable to track the current slide:

* **Action**: Set State
* **Variable**: `currentSlide`
* **Value**: `${index}`

Or display a toast with the slide number:

* **Action**: Show Toast
* **Message**: `${concat("Now viewing slide ", sum(index, 1))}`

{% hint style="info" %}
**Note:** Carousel does not support programmatic navigation via controllers or actions. All slide changes are triggered by user swipes or auto-play. Use the `On Changed` event to respond to slide transitions.
{% endhint %}

***

### Complete Setup Example

Here's a comprehensive example of setting up a Carousel for a product showcase:

#### 1. Data Source (API or Static)

**Static Example:**

```json
[
  {
    "productId": 1,
    "name": "Premium Headphones",
    "image": "https://example.com/headphones.jpg",
    "price": 299.99
  },
  {
    "productId": 2,
    "name": "Wireless Speaker",
    "image": "https://example.com/speaker.jpg",
    "price": 149.99
  },
  {
    "productId": 3,
    "name": "Smart Watch",
    "image": "https://example.com/watch.jpg",
    "price": 399.99
  }
]
```

#### 2. Carousel Configuration

* **Data Source:** Static array above or `${apiResponse.data.products}`
* **Height:** `300`
* **Aspect Ratio:** `16:9`
* **Direction:** `Horizontal`
* **Initial Page:** `0`
* **Viewport Fraction:** `0.85`
* **Enlarge Center Page:** `true`
* **Enlarge Factor:** `0.2`
* **Auto Play:** `true`
* **Auto Play Interval:** `4000` (4 seconds)
* **Animation Duration:** `600`
* **Infinite Scroll:** `true`
* **Show Indicator:** `true`
* **Dot Color:** `#CCCCCC`
* **Active Dot Color:** `#333333`

#### 3. Slide Template (Child Widget)

* **Container**
  * Padding: `16px`
  * Border Radius: `12px`
  * **Stack**
    * **Image**: `${currentItem.image}` (fills container)
    * **Positioned** (bottom gradient overlay)
      * **Column**
        * **Text**: `${currentItem.name}` (white, bold)
        * **Text**: `$${currentItem.price}` (white)

***

### Default Properties

The Carousel widget supports the **Layout** and **Appearance** sections from [Default Properties](https://docs.digia.tech/ui-building-blocks/widgets/default-properties). This includes:

* `Margin`
* `Background Color`
* `Border` and `Border Radius`
* `Visibility`

{% hint style="info" %}
**Note:** Padding is typically controlled by the slide template itself rather than the Carousel container. Add padding to your child widget template for consistent slide spacing.
{% endhint %}

***

### Guides

For comprehensive examples and real-world implementations, see:

{% content-ref url="<https://github.com/Digia-Technology-Private-Limited/digiaDocs/blob/main/docs/guides/carousel-image-sliders.md>" %}
<https://github.com/Digia-Technology-Private-Limited/digiaDocs/blob/main/docs/guides/carousel-image-sliders.md>
{% endcontent-ref %}

This guide includes:

* **Product Image Gallery** - Build professional product carousels with thumbnails and zoom
* **Onboarding Carousel** - Create interactive app tours with skip and navigation controls
* **Promotional Banners** - Implement auto-rotating marketing banners with CTAs
* **Featured Content Cards** - Design Netflix-style content showcases with peek effects
* Advanced patterns including vertical carousels, manual navigation, and parallax effects

***

### Best Practices

* **Limit the number of slides** to 3-7 items for optimal user experience.
* **Make slides tappable** by adding onClick actions to the child template to navigate to detail pages.
* **Use high-quality images** that are optimized for mobile (compressed but clear).
* **Provide alternative navigation** if using auto-play (dots, arrows, or swipe gestures).
* **Set appropriate auto-play intervals** (3-5 seconds minimum) so users can read content.
* **Use page indicators** to show users how many slides exist and their current position.
* **Test on different screen sizes** to ensure viewport fractions work well across devices.
* **Consider accessibility**: Auto-play can be disorienting for some users; provide pause controls.
* **Optimize slide templates**: Keep child widgets lightweight for smooth scrolling performance.
* **Use aspect ratios wisely**: Consistent aspect ratios create a professional, polished look.

### Use Cases

Carousel is ideal for:

* **Image Galleries**: Display product photos, portfolio images, or photo albums.
* **Featured Content**: Highlight promotions, announcements, or top stories.
* **Onboarding Screens**: Guide users through app features with tutorial slides.
* **Product Showcases**: Display product details, features, or variations.
* **Testimonials**: Rotate through customer reviews or success stories.
* **News & Articles**: Show latest news items or blog posts.
* **Promotional Banners**: Display rotating ads or special offers.
* **Before/After Comparisons**: Swipe between comparison images.
