PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.2.3
UiCore Elements – Free widgets and templates for Elementor v1.2.3
1.3.17 1.3.16 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 All 41 releases
uicore-elements / includes / widgets / custom-carousel.php

custom-carousel.php in UiCore Elements – Free widgets and templates for Elementor 1.2.3, at includes/widgets/custom-carousel.php

351 lines 10.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace UiCoreElements;
3 use Elementor\Plugin;
4 use Elementor\Controls_Manager;
5 use Elementor\Repeater;
6 use Elementor\Modules\NestedElements\Controls\Control_Nested_Repeater;
7 use UiCoreElements\Utils\Carousel_Trait;
8 use UiCoreElements\Utils\Animation_Trait;
9 use UiCoreElements\Utils\Item_Style_Component;
10
11 defined('ABSPATH') || exit();
12
13 /**
14 * Custom Carousel
15 *
16 * @author Lucas Marini Falbo <lucas@uicore.co>
17 * @since 1.0.7
18 */
19
20 class CustomCarousel extends UiCoreNestedWidget {
21
22 use Carousel_Trait;
23 use Animation_Trait;
24 use Item_Style_Component;
25
26 public function get_name()
27 {
28 return 'uicore-custom-carousel';
29 }
30 public function get_title()
31 {
32 return esc_html__('Custom Carousel', 'uicore-elements');
33 }
34 public function get_icon()
35 {
36 return 'eicon-carousel-loop ui-e-widget';
37 }
38 public function get_categories()
39 {
40 return ['uicore'];
41 }
42 public function get_keywords()
43 {
44 return ['slide', 'carousel', 'nested'];
45 }
46 public function get_styles()
47 {
48 $styles = [
49 'custom-carousel',
50 'carousel'
51 ];
52 return $styles;
53 }
54 public function get_scripts()
55 {
56 return $this->TRAIT_get_carousel_scripts(false);
57 }
58 public function has_widget_inner_wrapper(): bool {
59 // TODO: remove after 3.30, when the full deprecation of widget innet wrapper is ready
60 return ! \Elementor\Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
61 }
62
63 // Nested required functions
64 protected function carousel_content_container( int $index ) {
65 return [
66 'elType' => 'container',
67 'settings' => [
68 /* translators: %s: Item number */
69 '_title' => sprintf( esc_html__( 'Item #%s', 'uicore-elements' ), $index ),
70 'content_width' => 'full',
71 'flex_justify_content' => 'center',
72 'flex_align_items' => 'center',
73 ],
74 ];
75 }
76 protected function get_default_children_elements() {
77 return [
78 $this->carousel_content_container( 1 ),
79 $this->carousel_content_container( 2 ),
80 $this->carousel_content_container( 3 ),
81 ];
82 }
83 protected function get_default_repeater_title_setting_key() {
84 return 'carousel_item_title';
85 }
86 protected function get_default_children_title() {
87 /* translators: %d: Item number */
88 return esc_html__( 'Item #%d', 'uicore-elements' );
89 }
90 protected function get_default_children_placeholder_selector() {
91 return '.swiper-wrapper';
92 }
93
94 /**
95 * We've set a bool variable to this function because Custom Slider extends this widget and requires one extra control.
96 *
97 * @param bool $is_slider - If the widget is a slider, it will enable the slider height control.
98 */
99 protected function register_controls(bool $is_slider = false)
100 {
101
102 if( !Plugin::$instance->experiments->is_feature_active('nested-elements') ){
103 $this->nesting_fallback('controls');
104 return;
105 }
106
107 $this->start_controls_section(
108 'section_content',
109 [
110 'label' => __('Items', 'uicore-elements'),
111 'tab' => Controls_Manager::TAB_CONTENT,
112 ]
113 );
114
115 $repeater = new Repeater();
116
117 $repeater->add_control(
118 'carousel_item_title',
119 [
120 'label' => __('Title', 'uicore-elements'),
121 'type' => Controls_Manager::TEXT,
122 'render_type' => 'template',
123 'dynamic' => [
124 'active' => true,
125 ],
126 ]
127 );
128
129 $this->add_control(
130 'carousel_items',
131 [
132 'type' => Control_Nested_Repeater::CONTROL_TYPE,
133 'fields' => $repeater->get_controls(),
134 'default' => [
135 [ 'carousel_item_title' => __( 'Item #1', 'uicore-elements' ) ],
136 [ 'carousel_item_title' => __( 'Item #2', 'uicore-elements' ) ],
137 [ 'carousel_item_title' => __( 'Item #3', 'uicore-elements' ) ],
138 ]
139 ]
140 );
141
142 $this->end_controls_section();
143
144 // Additional Carousel Controls
145 $this->start_controls_section(
146 'section_additional_settings',
147 [
148 'label' => __('Additional Settings', 'uicore-elements'),
149 'tab' => Controls_Manager::TAB_CONTENT,
150 ]
151 );
152
153 $this->TRAIT_register_carousel_additional_controls($is_slider); // Carousel Additionals
154
155 $this->end_controls_section();
156
157 $this->start_controls_section(
158 'section_carousel_settings',
159 [
160 'label' => __('Carousel Settings', 'uicore-elements'),
161 ]
162 );
163
164 $this->TRAIT_register_carousel_settings_controls(); // Carousel settings
165
166 $this->end_controls_section();
167
168 $this->TRAIT_register_navigation_controls(); // Navigation settings
169
170 $this->start_controls_section(
171 'section_style_review_items',
172 [
173 'label' => esc_html__( 'Items', 'uicore-elements' ),
174 'tab' => Controls_Manager::TAB_STYLE,
175 ]
176 );
177
178 $this->TRAIT_register_all_item_style_controls();
179
180 $this->end_controls_section();
181
182 $this->TRAIT_register_navigation_style_controls(); // Carousel Navigation Styles
183
184 // Decrease default item padding
185 $this->update_control('item_padding', [
186 'default' => [
187 'top' => 25,
188 'right' => 25,
189 'bottom' => 25,
190 'left' => 25,
191 'unit' => 'px',
192 'isLinked' => true,
193 ],
194 ]);
195
196 // Adds description to loop
197 $this->update_control('loop', [
198 'description' => esc_html__('Loop preview is disabled here on the editor, due to compatibility issues. But you can test on the front-end, since it works outside the editor.', 'uicore-elements'),
199 ]);
200
201 }
202
203 public function render()
204 {
205 if( Plugin::$instance->experiments->is_feature_active('nested-elements') == false ){
206 $this->nesting_fallback();
207 return;
208 }
209
210 $items = $this->get_settings_for_display('carousel_items');
211 $carousel_items = '';
212
213 $total_slides = count($items);
214 $should_duplicate = $this->TRAIT_should_duplicate_slides($total_slides);
215 $duplicated_slides = [];
216
217 foreach ( $items as $index => $item ) {
218 ob_start();
219 $this->render_item($index);
220 $current_slide = ob_get_clean();
221
222 if($should_duplicate){
223 $duplicated_slides[$index] = $current_slide;
224 }
225
226 $carousel_items .= $current_slide;
227 }
228
229 // Most recent swiper versions requires, if loop, at least one extra slide compared to visible slides
230 if($should_duplicate) {
231 $diff = $this->TRAIT_get_duplication_diff($total_slides);
232 for($i = 0; $i <= $diff; $i++){
233 $carousel_items .= $duplicated_slides[$i];
234 }
235 }
236
237 ?>
238 <div class="ui-e-carousel swiper">
239
240 <div class='swiper-wrapper'>
241 <?php echo $carousel_items; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
242 </div>
243
244 </div>
245
246 <?php $this->TRAIT_render_carousel_navigations(); ?>
247 <?php
248 }
249
250 public function render_item( $index ) {
251 ?>
252 <div class="ui-e-wrp swiper-slide" data-hash="<?php echo esc_html($index);?>">
253 <?php $this->print_child( $index ); ?>
254 </div>
255 <?php
256 }
257
258 public function print_child( $index ) {
259 $children = $this->get_children();
260 $child_ids = [];
261
262 if( empty( $children )){
263 return;
264 }
265
266 foreach ( $children as $child ) {
267 $child_ids[] = $child->get_id();
268 }
269
270 add_filter( 'elementor/frontend/container/should_render', function( $should_render, $container ) use ($child_ids) {
271 return $this->add_child_attributes($should_render, $container, $child_ids);
272 }, 10, 3 );
273
274 $children[ $index ]->print_element();
275
276 remove_filter( 'elementor/frontend/container/should_render', [$this, 'add_child_attributes'] );
277 }
278
279 /**
280 * Adds attributes to child elements containers.
281 */
282 protected function add_child_attributes($should_render, $container, $child_ids, $classnames = ['ui-e-item'])
283 {
284
285 // custom cases may be added here
286
287 if ( in_array( $container->get_id(), $child_ids ) ) {
288 $container->add_render_attribute( '_wrapper', [
289 'class' => $classnames,
290 ]);
291 }
292
293 return $should_render;
294 }
295
296 protected function get_initial_config(): array {
297 if ( Plugin::$instance->experiments->is_feature_active( 'e_nested_atomic_repeaters' ) ) {
298 return array_merge( parent::get_initial_config(), [
299 'support_improved_repeaters' => true,
300 'node' => 'button',
301 ] );
302 }
303
304 return parent::get_initial_config();
305 }
306
307 protected function content_template() {
308
309 if( Plugin::$instance->experiments->is_feature_active('nested-elements') == false ){
310 return;
311 }
312
313 ?>
314 <#
315 var carouselItems = settings.carousel_items,
316 hideNavigation = settings.animation_style.includes('marquee'),
317 navigationDots = settings.navigation.includes('dots') && !hideNavigation,
318 navigationArrows = settings.navigation.includes('arrows') && !hideNavigation,
319 navigationFraction = settings.navigation.includes('fraction') && !hideNavigation;
320
321 var prev = elementor.helpers.renderIcon( view, settings.previous_arrow, { 'aria-hidden': true }, 'i' , 'object' ),
322 next = elementor.helpers.renderIcon( view, settings.next_arrow, { 'aria-hidden': true }, 'i' , 'object' );
323 #>
324
325 <div class="ui-e-carousel swiper {{ elementorFrontend.config.swiperClass }}">
326 <div class='swiper-wrapper'> </div>
327 </div>
328
329 <# if ( navigationDots ) { #>
330 <div class="swiper-pagination ui-e-dots ui-e-carousel-dots"></div>
331 <# } #>
332 <# if ( navigationArrows ) { #>
333 <div class="ui-e-button ui-e-carousel-button ui-e-previous" role="button" aria-label="Previous slide">
334 {{{ prev.value }}}
335 </div>
336 <div class="ui-e-button ui-e-carousel-button ui-e-next" role="button" aria-label="Next slide">
337 {{{ next.value }}}
338 </div>
339 <# } #>
340 <# if ( navigationFraction ) { #>
341 <div class="ui-e-fraction ui-e-carousel-fraction">
342 <span class="ui-e-current"></span>
343 /
344 <span class="ui-e-total"></span>
345 </div>
346 <# } #>
347 <?php
348 }
349
350 }
351 \Elementor\Plugin::instance()->widgets_manager->register(new CustomCarousel());