if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Modules\Promotions\Controls\Promotion_Control;
* Elementor image carousel widget.
* Elementor widget that displays a set of images in a rotating carousel or
class Widget_Image_Carousel extends Widget_Base {
* Retrieve image carousel widget name.
* @return string Widget name.
public function get_name() {
* Retrieve image carousel widget title.
* @return string Widget title.
public function get_title() {
return esc_html__( 'Image Carousel', 'elementor' );
* Retrieve image carousel widget icon.
* @return string Widget icon.
public function get_icon() {
return 'eicon-slider-push';
* Retrieve the list of keywords the widget belongs to.
* @return array Widget keywords.
public function get_keywords() {
return [ 'image', 'photo', 'visual', 'carousel', 'slider' ];
protected function is_dynamic_content(): bool {
* Get style dependencies.
* Retrieve the list of style dependencies the widget requires.
* @return array Widget style dependencies.
public function get_style_depends(): array {
return [ 'e-swiper', 'widget-image-carousel' ];
* Get script dependencies.
* Retrieve the list of script dependencies the widget requires.
* @return array Widget script dependencies.
public function get_script_depends(): array {
public function has_widget_inner_wrapper(): bool {
return ! Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
* Get widget upsale data.
* Retrieve the widget promotion data.
* @return array Widget promotion data.
protected function get_upsale_data() {
'condition' => ! Utils::has_pro(),
'image' => esc_url( ELEMENTOR_ASSETS_URL . 'images/go-pro.svg' ),
'image_alt' => esc_attr__( 'Upgrade', 'elementor' ),
'description' => esc_html__( 'Gain complete freedom to design every slide with Elementor"s Pro Carousel.', 'elementor' ),
'upgrade_url' => esc_url( 'https://go.elementor.com/go-pro-image-carousel-widget/' ),
'upgrade_text' => esc_html__( 'Upgrade Now', 'elementor' ),
* Register image carousel widget controls.
* Adds different input fields to allow the user to change and customize the widget settings.
protected function register_controls() {
$this->start_controls_section(
'section_image_carousel',
'label' => esc_html__( 'Image Carousel', 'elementor' ),
'label' => esc_html__( 'Carousel Name', 'elementor' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Image Carousel', 'elementor' ),
'label' => esc_html__( 'Add Images', 'elementor' ),
'type' => Controls_Manager::GALLERY,
$this->add_group_control(
Group_Control_Image_Size::get_type(),
'name' => 'thumbnail', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `thumbnail_size` and `thumbnail_custom_dimension`.
$slides_to_show = range( 1, 10 );
$slides_to_show = array_combine( $slides_to_show, $slides_to_show );
$this->add_responsive_control(
'label' => esc_html__( 'Slides to Show', 'elementor' ),
'type' => Controls_Manager::SELECT,
'' => esc_html__( 'Default', 'elementor' ),
'frontend_available' => true,
'render_type' => 'template',
'{{WRAPPER}}' => '--e-image-carousel-slides-to-show: {{VALUE}}',
'content_classes' => 'elementor-control-field-select-small',
$this->add_responsive_control(
'label' => esc_html__( 'Slides to Scroll', 'elementor' ),
'type' => Controls_Manager::SELECT,
'description' => esc_html__( 'Set how many slides are scrolled per swipe.', 'elementor' ),
'' => esc_html__( 'Default', 'elementor' ),
'slides_to_show!' => '1',
'frontend_available' => true,
'content_classes' => 'elementor-control-field-select-small',
'label' => esc_html__( 'Image Stretch', 'elementor' ),
'type' => Controls_Manager::SELECT,
'no' => esc_html__( 'No', 'elementor' ),
'yes' => esc_html__( 'Yes', 'elementor' ),
'label' => esc_html__( 'Navigation', 'elementor' ),
'type' => Controls_Manager::SELECT,
'both' => esc_html__( 'Arrows and Dots', 'elementor' ),
'arrows' => esc_html__( 'Arrows', 'elementor' ),
'dots' => esc_html__( 'Dots', 'elementor' ),
'none' => esc_html__( 'None', 'elementor' ),
'frontend_available' => true,
'navigation_previous_icon',
'label' => esc_html__( 'Previous Arrow Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'fa4compatibility' => 'icon',
'icon' => 'eicon-chevron-left',
'label' => esc_html__( 'Next Arrow Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'fa4compatibility' => 'icon',
'icon' => 'eicon-chevron-right',
'arrow-alt-circle-right',
'arrow-alt-circle-right',
'label' => esc_html__( 'Link', 'elementor' ),
'type' => Controls_Manager::SELECT,
'none' => esc_html__( 'None', 'elementor' ),
'file' => esc_html__( 'Media File', 'elementor' ),
'custom' => esc_html__( 'Custom URL', 'elementor' ),
'label' => esc_html__( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'label' => esc_html__( 'Lightbox', 'elementor' ),
'type' => Controls_Manager::SELECT,
'description' => sprintf(
/* translators: 1: Link open tag, 2: Link close tag. */
esc_html__( 'Manage your site’s lightbox settings in the %1$sLightbox panel%2$s.', 'elementor' ),
'<a href="javascript: $e.run( \'panel/global/open\' ).then( () => $e.route( \'panel/global/settings-lightbox\' ) )">',
'default' => esc_html__( 'Default', 'elementor' ),
'yes' => esc_html__( 'Yes', 'elementor' ),
'no' => esc_html__( 'No', 'elementor' ),
'label' => esc_html__( 'Caption', 'elementor' ),
'type' => Controls_Manager::SELECT,
'' => esc_html__( 'None', 'elementor' ),
'title' => esc_html__( 'Title', 'elementor' ),
'caption' => esc_html__( 'Caption', 'elementor' ),
'description' => esc_html__( 'Description', 'elementor' ),
$this->end_controls_section();
$this->start_controls_section(
'section_additional_options',
'label' => esc_html__( 'Additional Options', 'elementor' ),
'label' => esc_html__( 'Lazyload', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'frontend_available' => true,
'label' => esc_html__( 'Autoplay', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Yes', 'elementor' ),
'label_off' => esc_html__( 'No', 'elementor' ),
'frontend_available' => true,
'label' => esc_html__( 'Pause on Hover', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Yes', 'elementor' ),
'label_off' => esc_html__( 'No', 'elementor' ),
'frontend_available' => true,
'label' => esc_html__( 'Pause on Interaction', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Yes', 'elementor' ),
'label_off' => esc_html__( 'No', 'elementor' ),
'frontend_available' => true,
'label' => esc_html__( 'Autoplay Speed', 'elementor' ),
'type' => Controls_Manager::NUMBER,
'frontend_available' => true,
// Loop requires a re-render so no 'render_type = none'