PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.2.1
UiCore Elements – Free widgets and templates for Elementor v1.2.1
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.1, at includes/widgets/custom-carousel.php

341 lines 10.6 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 // TODO: remove or set as false, after 3.30, when the full deprecation of widget innet wrapper is ready
59 public function has_widget_inner_wrapper(): bool {
60 return true;
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 the `ui-e-item` class directly on the item container
271 $add_attribute_to_container = function ( $should_render, $container ) use ( $child_ids ) {
272 if ( in_array( $container->get_id(), $child_ids ) ) {
273 $container->add_render_attribute( '_wrapper', [
274 'class' => 'ui-e-item',
275 ] );
276 }
277
278 return $should_render;
279 };
280
281 add_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container, 10, 3 );
282 $children[ $index ]->print_element();
283 remove_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container );
284 }
285
286 protected function get_initial_config(): array {
287 if ( Plugin::$instance->experiments->is_feature_active( 'e_nested_atomic_repeaters' ) ) {
288 return array_merge( parent::get_initial_config(), [
289 'support_improved_repeaters' => true,
290 'node' => 'button',
291 ] );
292 }
293
294 return parent::get_initial_config();
295 }
296
297 protected function content_template() {
298
299 if( Plugin::$instance->experiments->is_feature_active('nested-elements') == false ){
300 return;
301 }
302
303 ?>
304 <#
305 var carouselItems = settings.carousel_items,
306 hideNavigation = settings.animation_style.includes('marquee'),
307 navigationDots = settings.navigation.includes('dots') && !hideNavigation,
308 navigationArrows = settings.navigation.includes('arrows') && !hideNavigation,
309 navigationFraction = settings.navigation.includes('fraction') && !hideNavigation;
310
311 var prev = elementor.helpers.renderIcon( view, settings.previous_arrow, { 'aria-hidden': true }, 'i' , 'object' ),
312 next = elementor.helpers.renderIcon( view, settings.next_arrow, { 'aria-hidden': true }, 'i' , 'object' );
313 #>
314
315 <div class="ui-e-carousel swiper {{ elementorFrontend.config.swiperClass }}">
316 <div class='swiper-wrapper'> </div>
317 </div>
318
319 <# if ( navigationDots ) { #>
320 <div class="swiper-pagination ui-e-dots ui-e-carousel-dots"></div>
321 <# } #>
322 <# if ( navigationArrows ) { #>
323 <div class="ui-e-button ui-e-carousel-button ui-e-previous" role="button" aria-label="Previous slide">
324 {{{ prev.value }}}
325 </div>
326 <div class="ui-e-button ui-e-carousel-button ui-e-next" role="button" aria-label="Next slide">
327 {{{ next.value }}}
328 </div>
329 <# } #>
330 <# if ( navigationFraction ) { #>
331 <div class="ui-e-fraction ui-e-carousel-fraction">
332 <span class="ui-e-current"></span>
333 /
334 <span class="ui-e-total"></span>
335 </div>
336 <# } #>
337 <?php
338 }
339
340 }
341 \Elementor\Plugin::instance()->widgets_manager->register(new CustomCarousel());