# Flip Carousel Widget

> 3D rotary carousel using jQuery Flipster — items rotate in/out of perspective (coverflow / wheel-style). Source can be Lite-shared posts or manually defined Repeater items.

**Class file:** `includes/Elements/Flip_Carousel.php` (950 lines)
**Slug:** `flip-carousel` (widget id `eael-flip-carousel`)
**Public docs:** <https://essential-addons.com/elementor/docs/flip-carousel/>
**Pro-shared:** Pro-only. Uses Lite's `Classes\Helper`. Vendor lib: jQuery Flipster.

## Overview

Renders a 3D-perspective carousel where items rotate through the viewport. Vendor library is **jQuery Flipster** (`jquery.flipster.min.js` / `.css`) — distinct from Swiper. Source can be a WP posts loop or a manual Repeater. Multiple flip "styles" (coverflow, carousel, flat) configurable per Flipster's options.

## Pro vs Lite

Pro-only.

## File Map

| File | Role |
| --- | --- |
| `includes/Elements/Flip_Carousel.php` | Widget class (950 lines) |
| `src/css/view/flip-carousel.scss` → `assets/front-end/css/view/flip-carousel.min.css` | Pro-side styling |
| `src/js/view/flip-carousel.js` → `assets/front-end/js/view/flip-carousel.min.js` | Flipster init |
| `assets/front-end/css/lib-view/flipster/jquery.flipster.min.css` | Vendor — Flipster CSS |
| `assets/front-end/js/lib-view/flipster/jquery.flipster.min.js` | Vendor — Flipster JS |
| `config.php` entry `'flip-carousel'` | lib CSS + Pro CSS + lib JS + Pro JS |

## Architecture

- **jQuery Flipster, not Swiper** — distinguishes from sibling carousel widgets. Flipster does 3D rotational transforms; Swiper doesn't. Pro ships its own bundled copy under `lib-view/flipster/`.
- **Composes Lite's `Helper`** (line 12) — uses query helpers for the posts-source mode.
- **Dual source mode** — dynamic posts OR custom Repeater. Same pattern as Content_Timeline.
- **Smallest carousel widget at 950 lines** — manageable single-template render.

## Render Output

```html
<div class="eael-flip-carousel-wrap">
  <ul class="flipster">
    <li class="eael-flip-item" data-flip-item="0">
      <img src="{image}" />
      [?] <div class="eael-flip-content">
        <h3>{title}</h3>
        <p>{description}</p>
      </div>
    </li>
    ...
  </ul>
</div>
```

Flipster wraps the `<ul>` post-init with extra positioning divs.

## Controls Reference

| Control id | Tab → Section | Type | Purpose |
| --- | --- | --- | --- |
| Source (dynamic / custom) | Content → Source | CHOOSE | Two-mode toggle |
| Query controls | Content → Query | various | When source = dynamic |
| Custom items Repeater | Content → Custom | REPEATER | When source = custom |
| Flipster style | Content → Carousel | SELECT | `coverflow` / `carousel` / `flat` |
| Item count visible | Content → Carousel | NUMBER | Items in viewport |
| Buttons (prev/next/nav) | Content → Carousel | SWITCHER | Flipster nav buttons |
| Keyboard navigation | Content → Carousel | SWITCHER | Flipster keyboard option |

## Conditional Dependencies

```text
source = 'dynamic' → query controls visible
source = 'custom'  → Repeater visible
nav = 'yes' → nav-thumbnail style controls
buttons = 'yes' → prev/next button style controls
```

## JavaScript Lifecycle

`src/js/view/flip-carousel.js`:

```js
var FlipCarouselHandler = function( $scope, $ ) {
    var $list = $scope.find( '.flipster' );
    var opts = {
        style: $list.data( 'style' ),
        spacing: -0.7,
        buttons: $list.data( 'buttons' ),
        // ...
    };
    $list.flipster( opts );
};
```

## Hooks & Filters

Standard widget render. No Pro-emitted hooks.

## Common Issues

| Symptom | Likely cause | Diagnose | Fix |
| --- | --- | --- | --- |
| Items don't rotate | Flipster not loaded | DevTools: check `$.fn.flipster` | Verify `jquery.flipster.min.js` enqueued via `config.php` |
| 3D transform missing | Browser doesn't support CSS perspective | Inspect parent perspective | Modern browsers all support; check no `transform: none` override |
| Custom items render but no images | MEDIA control unset | Inspect Repeater values | Set image per item |
| Editor preview broken | Flipster requires DOM ready | `isEditMode` re-init missing | Ensure JS re-inits after Elementor preview reload |
| Performance jank on scroll | Many items + heavy images | Inspect FPS | Reduce item count or use smaller thumbnails |

## Known Limitations

- **Flipster is jQuery-based** — depends on jQuery being present (always true on WP, but architectural debt)
- **Not lazy-loaded** — Flipster requires all items in DOM at init
- **No `prefers-reduced-motion`** — animation runs regardless
- **Vendor lib unmaintained upstream** — Flipster last released years ago; security / browser-compat drift over time
- **Items count UI** — Flipster's "visible items" interacts with viewport width; manual count override has edge cases
- **Heavy CSS transforms** — older mobile devices may stutter

## Cross-References

- Sibling: [`logo-carousel.md`](logo-carousel.md), [`team-member-carousel.md`](team-member-carousel.md), [`testimonial-slider.md`](testimonial-slider.md), [`post-carousel.md`](post-carousel.md)
- Shared patterns: [`_patterns.md`](_patterns.md)
