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

337 lines 10.5 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
59 // Nested required functions
60 protected function carousel_content_container( int $index ) {
61 return [
62 'elType' => 'container',
63 'settings' => [
64 /* translators: %s: Item number */
65 '_title' => sprintf( esc_html__( 'Item #%s', 'uicore-elements' ), $index ),
66 'content_width' => 'full',
67 'flex_justify_content' => 'center',
68 'flex_align_items' => 'center',
69 ],
70 ];
71 }
72 protected function get_default_children_elements() {
73 return [
74 $this->carousel_content_container( 1 ),
75 $this->carousel_content_container( 2 ),
76 $this->carousel_content_container( 3 ),
77 ];
78 }
79 protected function get_default_repeater_title_setting_key() {
80 return 'carousel_item_title';
81 }
82 protected function get_default_children_title() {
83 /* translators: %d: Item number */
84 return esc_html__( 'Item #%d', 'uicore-elements' );
85 }
86 protected function get_default_children_placeholder_selector() {
87 return '.swiper-wrapper';
88 }
89
90 /**
91 * We've set a bool variable to this function because Custom Slider extends this widget and requires one extra control.
92 *
93 * @param bool $is_slider - If the widget is a slider, it will enable the slider height control.
94 */
95 protected function register_controls(bool $is_slider = false)
96 {
97
98 if( !Plugin::$instance->experiments->is_feature_active('nested-elements') ){
99 $this->nesting_fallback('controls');
100 return;
101 }
102
103 $this->start_controls_section(
104 'section_content',
105 [
106 'label' => __('Items', 'uicore-elements'),
107 'tab' => Controls_Manager::TAB_CONTENT,
108 ]
109 );
110
111 $repeater = new Repeater();
112
113 $repeater->add_control(
114 'carousel_item_title',
115 [
116 'label' => __('Title', 'uicore-elements'),
117 'type' => Controls_Manager::TEXT,
118 'render_type' => 'template',
119 'dynamic' => [
120 'active' => true,
121 ],
122 ]
123 );
124
125 $this->add_control(
126 'carousel_items',
127 [
128 'type' => Control_Nested_Repeater::CONTROL_TYPE,
129 'fields' => $repeater->get_controls(),
130 'default' => [
131 [ 'carousel_item_title' => __( 'Item #1', 'uicore-elements' ) ],
132 [ 'carousel_item_title' => __( 'Item #2', 'uicore-elements' ) ],
133 [ 'carousel_item_title' => __( 'Item #3', 'uicore-elements' ) ],
134 ]
135 ]
136 );
137
138 $this->end_controls_section();
139
140 // Additional Carousel Controls
141 $this->start_controls_section(
142 'section_additional_settings',
143 [
144 'label' => __('Additional Settings', 'uicore-elements'),
145 'tab' => Controls_Manager::TAB_CONTENT,
146 ]
147 );
148
149 $this->TRAIT_register_carousel_additional_controls($is_slider); // Carousel Additionals
150
151 $this->end_controls_section();
152
153 $this->start_controls_section(
154 'section_carousel_settings',
155 [
156 'label' => __('Carousel Settings', 'uicore-elements'),
157 ]
158 );
159
160 $this->TRAIT_register_carousel_settings_controls(); // Carousel settings
161
162 $this->end_controls_section();
163
164 $this->TRAIT_register_navigation_controls(); // Navigation settings
165
166 $this->start_controls_section(
167 'section_style_review_items',
168 [
169 'label' => esc_html__( 'Items', 'uicore-elements' ),
170 'tab' => Controls_Manager::TAB_STYLE,
171 ]
172 );
173
174 $this->TRAIT_register_all_item_style_controls();
175
176 $this->end_controls_section();
177
178 $this->TRAIT_register_navigation_style_controls(); // Carousel Navigation Styles
179
180 // Decrease default item padding
181 $this->update_control('item_padding', [
182 'default' => [
183 'top' => 25,
184 'right' => 25,
185 'bottom' => 25,
186 'left' => 25,
187 'unit' => 'px',
188 'isLinked' => true,
189 ],
190 ]);
191
192 // Adds description to loop
193 $this->update_control('loop', [
194 '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'),
195 ]);
196
197 }
198
199 public function render()
200 {
201 if( Plugin::$instance->experiments->is_feature_active('nested-elements') == false ){
202 $this->nesting_fallback();
203 return;
204 }
205
206 $items = $this->get_settings_for_display('carousel_items');
207 $carousel_items = '';
208
209 $total_slides = count($items);
210 $should_duplicate = $this->TRAIT_should_duplicate_slides($total_slides);
211 $duplicated_slides = [];
212
213 foreach ( $items as $index => $item ) {
214 ob_start();
215 $this->render_item($index);
216 $current_slide = ob_get_clean();
217
218 if($should_duplicate){
219 $duplicated_slides[$index] = $current_slide;
220 }
221
222 $carousel_items .= $current_slide;
223 }
224
225 // Most recent swiper versions requires, if loop, at least one extra slide compared to visible slides
226 if($should_duplicate) {
227 $diff = $this->TRAIT_get_duplication_diff($total_slides);
228 for($i = 0; $i <= $diff; $i++){
229 $carousel_items .= $duplicated_slides[$i];
230 }
231 }
232
233 ?>
234 <div class="ui-e-carousel swiper">
235
236 <div class='swiper-wrapper'>
237 <?php echo $carousel_items; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
238 </div>
239
240 </div>
241
242 <?php $this->TRAIT_render_carousel_navigations(); ?>
243 <?php
244 }
245
246 public function render_item( $index ) {
247 ?>
248 <div class="ui-e-wrp swiper-slide" data-hash="<?php echo esc_html($index);?>">
249 <?php $this->print_child( $index ); ?>
250 </div>
251 <?php
252 }
253
254 public function print_child( $index ) {
255 $children = $this->get_children();
256 $child_ids = [];
257
258 if( empty( $children )){
259 return;
260 }
261
262 foreach ( $children as $child ) {
263 $child_ids[] = $child->get_id();
264 }
265
266 // Add the `ui-e-item` class directly on the item container
267 $add_attribute_to_container = function ( $should_render, $container ) use ( $child_ids ) {
268 if ( in_array( $container->get_id(), $child_ids ) ) {
269 $container->add_render_attribute( '_wrapper', [
270 'class' => 'ui-e-item',
271 ] );
272 }
273
274 return $should_render;
275 };
276
277 add_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container, 10, 3 );
278 $children[ $index ]->print_element();
279 remove_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container );
280 }
281
282 protected function get_initial_config(): array {
283 if ( Plugin::$instance->experiments->is_feature_active( 'e_nested_atomic_repeaters' ) ) {
284 return array_merge( parent::get_initial_config(), [
285 'support_improved_repeaters' => true,
286 'node' => 'button',
287 ] );
288 }
289
290 return parent::get_initial_config();
291 }
292
293 protected function content_template() {
294
295 if( Plugin::$instance->experiments->is_feature_active('nested-elements') == false ){
296 return;
297 }
298
299 ?>
300 <#
301 var carouselItems = settings.carousel_items,
302 hideNavigation = settings.animation_style.includes('marquee'),
303 navigationDots = settings.navigation.includes('dots') && !hideNavigation,
304 navigationArrows = settings.navigation.includes('arrows') && !hideNavigation,
305 navigationFraction = settings.navigation.includes('fraction') && !hideNavigation;
306
307 var prev = elementor.helpers.renderIcon( view, settings.previous_arrow, { 'aria-hidden': true }, 'i' , 'object' ),
308 next = elementor.helpers.renderIcon( view, settings.next_arrow, { 'aria-hidden': true }, 'i' , 'object' );
309 #>
310
311 <div class="ui-e-carousel swiper {{ elementorFrontend.config.swiperClass }}">
312 <div class='swiper-wrapper'> </div>
313 </div>
314
315 <# if ( navigationDots ) { #>
316 <div class="swiper-pagination ui-e-dots ui-e-carousel-dots"></div>
317 <# } #>
318 <# if ( navigationArrows ) { #>
319 <div class="ui-e-button ui-e-carousel-button ui-e-previous" role="button" aria-label="Previous slide">
320 {{{ prev.value }}}
321 </div>
322 <div class="ui-e-button ui-e-carousel-button ui-e-next" role="button" aria-label="Next slide">
323 {{{ next.value }}}
324 </div>
325 <# } #>
326 <# if ( navigationFraction ) { #>
327 <div class="ui-e-fraction ui-e-carousel-fraction">
328 <span class="ui-e-current"></span>
329 /
330 <span class="ui-e-total"></span>
331 </div>
332 <# } #>
333 <?php
334 }
335
336 }
337 \Elementor\Plugin::instance()->widgets_manager->register(new CustomCarousel());