# Testimonial Slider Widget

> Swiper-based testimonial carousel — quote + author photo / name / role / company / rating. Multiple layout variations driven by control flags.

**Class file:** `includes/Elements/Testimonial_Slider.php` (2,471 lines)
**Slug:** `testimonial-slider` (widget id `eael-testimonial-slider`)
**Public docs:** <https://essential-addons.com/elementor/docs/testimonial-slider/>
**Pro-shared:** Pro-only. Uses Pro's `Helper` (not Lite's). Elementor `e-swiper` handle.

## Overview

Customer-quote carousel. Each Repeater row is a testimonial — quote text, author name, position, company, rating (star count), photo. Multiple visual variations: quote-icon position, rating-icon style, author-photo layout. Uses Pro's own `Helper` for some utility methods (line 13: `Essential_Addons_Elementor\Pro\Classes\Helper as HelperClass`).

## Pro vs Lite

Pro-only widget. Lite has a static Testimonial widget; this Pro widget is multi-item carousel.

## File Map

| File | Role |
| --- | --- |
| `includes/Elements/Testimonial_Slider.php` | Widget class (2,471 lines) |
| `src/css/view/testimonial-slider.scss` → `assets/front-end/css/view/testimonial-slider.min.css` | Styling |
| `src/js/view/testimonial-slider.js` → `assets/front-end/js/view/testimonial-slider.min.js` | Swiper init |
| `config.php` entry `'testimonial-slider'` | Self CSS + self JS |

`get_style_depends()` returns `['e-swiper']` (line 71–76).

## Architecture

- **`get_style_depends() => ['e-swiper']`** — Elementor Swiper handle.
- **Composes Pro's `Helper`** — atypical (most carousel widgets use Lite's). Pro's `Helper` may provide testimonial-specific helpers (verify in code).
- **Star rating control** — likely a SELECT (1–5) per testimonial; rendered as filled/empty star icons.
- **Per-element show toggles** — quote icon, author photo, position, company, rating each have show/hide switchers, drove substantial per-element style controls.
- **Standard `swiper-container-wrap` arrow buttons + pagination.**
- **No template directory** — single inline render.

## Render Output

```html
<div class="swiper-container-wrap eael-testimonial-slider-{element-id}">
  <div class="eael-testimonial-slider swiper">
    <div class="swiper-wrapper">
      <div class="swiper-slide">
        <div class="eael-testimonial-card">
          [?] <span class="eael-quote-icon"><i class="fa-quote-left"></i></span>
          <blockquote class="eael-testimonial-quote">{quote_text}</blockquote>
          [?] <div class="eael-testimonial-rating">
            <i class="star filled"></i><i class="star filled"></i>...
          </div>
          <div class="eael-testimonial-author">
            [?] <img class="author-photo" src="{photo}" />
            <div class="author-meta">
              <h4 class="author-name">{name}</h4>
              [?] <span class="author-position">{position}</span>
              [?] <span class="author-company">{company}</span>
            </div>
          </div>
        </div>
      </div>
      ...
    </div>
    [?] <div class="swiper-button-next"></div>
    [?] <div class="swiper-button-prev"></div>
    [?] <div class="swiper-pagination"></div>
  </div>
</div>
```

## Controls Reference

| Control id | Tab → Section | Type | Purpose |
| --- | --- | --- | --- |
| Testimonials Repeater | Content → Testimonials | REPEATER | One row per quote |
| (Per-item) quote text | Inside Repeater | TEXTAREA | Quote body |
| (Per-item) author name / position / company | Inside Repeater | TEXT × 3 | Identity |
| (Per-item) author photo | Inside Repeater | MEDIA | Photo |
| (Per-item) rating | Inside Repeater | SELECT | Star count (0–5) |
| Show quote icon / photo / position / company / rating | Content → Display | SWITCHER | Per-element visibility |
| Quote icon picker | Content → Icons | ICONS | Quote SVG / FA5 |
| Rating star icon | Content → Icons | ICONS | Star FA5 icon (filled / empty) |
| Carousel autoplay / arrows / dots / effect | Content → Carousel | various | Swiper config |
| Per-region styling | Style → ... | various | Quote / author / rating / arrow styling |

## Conditional Dependencies

```text
show_quote_icon = 'yes' → quote icon picker + style visible
show_rating = 'yes' → star icon + rating style controls visible
show_photo = 'yes' → photo size + border-radius controls visible
arrows = 'yes' → arrow icon pickers
dots = 'yes' → pagination style
```

## JavaScript Lifecycle

Standard Swiper init via `elementorFrontend.utils.swiper`. Possibly star-rating rendering helper if not pure-CSS.

## Hooks & Filters

Standard widget render. No Pro-emitted hooks.

## Common Issues

| Symptom | Likely cause | Diagnose | Fix |
| --- | --- | --- | --- |
| Rating shows wrong star count | SELECT value mismatch with render logic | Inspect setting | Verify rating value is integer 0–5; render loop iterates accordingly |
| Quote icon overlaps text on mobile | No responsive offset | Inspect `.eael-quote-icon` position | Add responsive position controls |
| Author photo too small | Image-size control on smaller bucket | Inspect rendered `<img>` | Use larger size or set explicit width |
| Slides differ in height | No equal-height enforcement | Inspect Swiper config | Add CSS flex / Swiper `autoHeight: false` |
| Long quote truncates | No max-line clamp | Inspect CSS | Add `-webkit-line-clamp` |

## Known Limitations

- **2,471 lines** — per-element controls bloat
- **Star rating likely hardcoded SELECT options** — adding 10-star rating requires control + render edits
- **No schema.org Review microdata** — testimonials should ideally emit Review schema for SEO; not implemented
- **Quote icon position is fixed** — top-left / top-right options only, not freeform
- **No `prefers-reduced-motion`** for autoplay
- **No animation per slide** (no Animate.css integration here, unlike Woo_Product_Slider)

## Cross-References

- Lite sibling: `Testimonials` (static)
- Sibling carousels: [`team-member-carousel.md`](team-member-carousel.md), [`logo-carousel.md`](logo-carousel.md), [`flip-carousel.md`](flip-carousel.md), [`post-carousel.md`](post-carousel.md)
- Shared patterns: [`_patterns.md`](_patterns.md)
