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 / tabs.php

tabs.php in UiCore Elements – Free widgets and templates for Elementor 1.2.0, at includes/widgets/tabs.php

1,623 lines 51.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
4 use Elementor\Controls_Manager;
5 use Elementor\Repeater;
6 use Elementor\Plugin;
7 use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
8 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
9 use Elementor\Group_Control_Background;
10 use Elementor\Group_Control_Border;
11 use Elementor\Group_Control_Box_Shadow;
12 use Elementor\Group_Control_Typography;
13 use Elementor\Icons_Manager;
14 use Elementor\Modules\NestedElements\Controls\Control_Nested_Repeater;
15
16 defined('ABSPATH') || exit();
17
18 /**
19 * Tabs
20 *
21 * @author Lucas Marini Falbo <lucas@uicore.co>
22 * @since 1.0.6
23 */
24
25 class Tabs extends UiCoreNestedWidget {
26
27 public function get_name() {
28 return 'uicore-tabs';
29 }
30 public function get_title() {
31 return esc_html__( 'Tabs', 'uicore-elements' );
32 }
33 public function get_icon() {
34 return 'eicon-tabs ui-e-widget';
35 }
36 public function get_categories()
37 {
38 return ['uicore'];
39 }
40 public function get_keywords() {
41 return [ 'tabs', 'tab', 'content' ];
42 }
43 public function get_styles()
44 {
45 return ['tabs'];
46 }
47 public function get_scripts()
48 {
49 return ['tabs'];
50 }
51 public function has_widget_inner_wrapper(): bool {
52 return false;
53 }
54
55 // Nested required functions
56 protected function tab_content_container( int $index ) {
57 return [
58 'elType' => 'container',
59 'settings' => [
60 /* translators: %s: Tab index */
61 '_title' => sprintf( __( 'Tab #%s', 'uicore-elements' ), $index ),
62 'content_width' => 'full',
63 ],
64 ];
65 }
66 protected function get_default_children_elements() {
67 return [
68 $this->tab_content_container( 1 ),
69 $this->tab_content_container( 2 ),
70 $this->tab_content_container( 3 ),
71 ];
72 }
73 protected function get_default_repeater_title_setting_key() {
74 return 'tab_title';
75 }
76 protected function get_default_children_title() {
77 /* translators: %d: Tab index */
78 return esc_html__( 'Tab #%d', 'uicore-elements' );
79 }
80 protected function get_default_children_placeholder_selector() {
81 return '.ui-e-tabs-content';
82 }
83
84 protected function register_controls() {
85
86 if( !Plugin::$instance->experiments->is_feature_active('nested-elements') ){
87 $this->nesting_fallback('controls');
88 return;
89 }
90
91 // Helper properties
92 $start = is_rtl() ? 'right' : 'left';
93 $end = is_rtl() ? 'left' : 'right';
94 $start_logical = is_rtl() ? 'end' : 'start';
95 $end_logical = is_rtl() ? 'start' : 'end';
96 $heading_selector = '{{WRAPPER}} > .ui-e-tabs > .ui-e-tabs-heading';
97 $content_selector = ':where( {{WRAPPER}} > .ui-e-tabs > .ui-e-tabs-content ) > .e-con';
98
99 $this->start_controls_section(
100 'section_tabs',
101 [
102 'label' => esc_html__( 'Tabs', 'uicore-elements' ),
103 'tab' => Controls_Manager::TAB_CONTENT,
104 ]
105 );
106
107 $repeater = new Repeater();
108
109 $repeater->add_control( 'tab_title', [
110 'label' => esc_html__( 'Title', 'uicore-elements' ),
111 'type' => Controls_Manager::TEXT,
112 'default' => esc_html__( 'Tab Title', 'uicore-elements' ),
113 'placeholder' => esc_html__( 'Tab Title', 'uicore-elements' ),
114 'label_block' => true,
115 'dynamic' => [
116 'active' => true,
117 ],
118 ] );
119
120 $repeater->add_control( 'tab_description', [
121 'label' => esc_html__( 'Description', 'uicore-elements' ),
122 'type' => Controls_Manager::TEXTAREA,
123 'rows' => 2,
124 'placeholder' => esc_html__( 'Tab Title', 'uicore-elements' ),
125 'label_block' => true,
126 'dynamic' => [
127 'active' => true,
128 ],
129 ] );
130
131 $repeater->add_control(
132 'tab_icon',
133 [
134 'label' => esc_html__( 'Icon', 'uicore-elements' ),
135 'type' => Controls_Manager::ICONS,
136 'fa4compatibility' => 'icon',
137 'skin' => 'inline',
138 'label_block' => false,
139 ]
140 );
141
142 $repeater->add_control(
143 'tab_icon_active',
144 [
145 'label' => esc_html__( 'Active Icon', 'uicore-elements' ),
146 'type' => Controls_Manager::ICONS,
147 'fa4compatibility' => 'icon',
148 'skin' => 'inline',
149 'label_block' => false,
150 'condition' => [
151 'tab_icon[value]!' => '',
152 ],
153 ]
154 );
155
156 $repeater->add_control(
157 'tab_id',
158 [
159 'label' => esc_html__( 'CSS ID', 'uicore-elements' ),
160 'type' => Controls_Manager::TEXT,
161 'default' => '',
162 'ai' => [
163 'active' => false,
164 ],
165 'dynamic' => [
166 'active' => true,
167 ],
168 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'uicore-elements' ),
169 'style_transfer' => false,
170 'classes' => 'elementor-control-direction-ltr',
171 ]
172 );
173
174 $this->add_control( 'tabs', [
175 'label' => esc_html__( 'Tabs Items', 'uicore-elements' ),
176 'type' => Control_Nested_Repeater::CONTROL_TYPE,
177 'fields' => $repeater->get_controls(),
178 'default' => [
179 [
180 'tab_title' => esc_html__( 'Tab #1', 'uicore-elements' ),
181 ],
182 [
183 'tab_title' => esc_html__( 'Tab #2', 'uicore-elements' ),
184 ],
185 [
186 'tab_title' => esc_html__( 'Tab #3', 'uicore-elements' ),
187 ],
188 ],
189 'title_field' => '{{{ tab_title }}}',
190 'button_text' => 'Add Tab',
191 ] );
192
193 // Tabs position and alignment group values
194 $styling_block_start = '--ui-e-tabs-direction: column; --ui-e-tabs-head-direction: row; --ui-e-tabs-head-width: initial; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-shrink: initial;';
195 $styling_block_end = '--ui-e-tabs-direction: column-reverse; --ui-e-tabs-head-direction: row; --ui-e-tabs-head-width: initial; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-shrink: initial;';
196 $styling_inline_end = '--ui-e-tabs-direction: row-reverse; --ui-e-tabs-head-direction: column; --ui-e-tabs-head-width: 240px; --ui-e-tabs-title-flex-basis: initial; --ui-e-tabs-title-flex-shrink: 0; --ui-e-tabs-title-width: 100%';
197 $styling_inline_start = '--ui-e-tabs-direction: row; --ui-e-tabs-head-direction: column; --ui-e-tabs-head-width: 240px; --ui-e-tabs-title-flex-basis: initial; --ui-e-tabs-title-flex-shrink: 0; --ui-e-tabs-title-width: 100%';
198
199 $this->add_responsive_control( 'tabs_direction', [
200 'label' => esc_html__( 'Tabs Direction', 'uicore-elements' ),
201 'type' => Controls_Manager::CHOOSE,
202 'options' => [
203 'block-start' => [
204 'title' => esc_html__( 'Above', 'uicore-elements' ),
205 'icon' => 'eicon-v-align-top',
206 ],
207 'block-end' => [
208 'title' => esc_html__( 'Below', 'uicore-elements' ),
209 'icon' => 'eicon-v-align-bottom',
210 ],
211 'inline-end' => [
212 'title' => esc_html__( 'After', 'uicore-elements' ),
213 'icon' => 'eicon-h-align-' . $end,
214 ],
215 'inline-start' => [
216 'title' => esc_html__( 'Before', 'uicore-elements' ),
217 'icon' => 'eicon-h-align-' . $start,
218 ],
219 ],
220 'default' => 'block-start',
221 'separator' => 'before',
222 'selectors_dictionary' => [
223 'block-start' => $styling_block_start,
224 'block-end' => $styling_block_end,
225 'inline-end' => $styling_inline_end,
226 'inline-start' => $styling_inline_start,
227 ],
228 'selectors' => [
229 '{{WRAPPER}}' => '{{VALUE}}',
230 ],
231 ] );
232
233 $this->add_responsive_control( 'tabs_width', [
234 'label' => esc_html__( 'Tabs Width', 'uicore-elements' ),
235 'type' => Controls_Manager::SLIDER,
236 'range' => [
237 '%' => [
238 'min' => 10,
239 'max' => 50,
240 ],
241 'px' => [
242 'min' => 20,
243 'max' => 600,
244 ],
245 ],
246 'default' => [
247 'unit' => '%',
248 ],
249 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
250 'selectors' => [
251 '{{WRAPPER}}' => '--ui-e-tabs-head-width: {{SIZE}}{{UNIT}}',
252 ],
253 'condition' => [
254 'tabs_direction' => [
255 'inline-start',
256 'inline-end',
257 ],
258 ],
259 ] );
260
261 $this->add_responsive_control( 'tabs_justify_horizontal', [
262 'label' => esc_html__( 'Justify', 'uicore-elements' ),
263 'type' => Controls_Manager::CHOOSE,
264 'options' => [
265 'start' => [
266 'title' => esc_html__( 'Start', 'uicore-elements' ),
267 'icon' => "eicon-align-$start_logical-h",
268 ],
269 'center' => [
270 'title' => esc_html__( 'Center', 'uicore-elements' ),
271 'icon' => 'eicon-align-center-h',
272 ],
273 'end' => [
274 'title' => esc_html__( 'End', 'uicore-elements' ),
275 'icon' => "eicon-align-$end_logical-h",
276 ],
277 'stretch' => [
278 'title' => esc_html__( 'Stretch', 'uicore-elements' ),
279 'icon' => 'eicon-align-stretch-h',
280 ],
281 ],
282 'selectors_dictionary' => [
283 'start' => 'justify-content: flex-start; --ui-e-tabs-title-flex-width: initial; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-title-flex-grow: 0;',
284 'center' => 'justify-content: center; --ui-e-tabs-title-flex-width: initial; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-title-flex-grow: 0;',
285 'end' => 'justify-content: flex-end; --ui-e-tabs-title-flex-width: initial; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-title-flex-grow: 0;',
286 'stretch' => 'justify-content: initial; --ui-e-tabs-title-flex-width: 100%; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-title-flex-grow: 1;',
287 ],
288 'selectors' => [
289 '{{WRAPPER}} .ui-e-tabs-heading' => '{{VALUE}}',
290 ],
291 'condition' => [
292 'tabs_direction' => [
293 'block-start',
294 'block-end',
295 ],
296 ],
297 'frontend_available' => true,
298 ] );
299
300 $this->add_responsive_control( 'tabs_justify_vertical', [
301 'label' => esc_html__( 'Tabs alignment', 'uicore-elements' ),
302 'type' => Controls_Manager::CHOOSE,
303 'options' => [
304 'start' => [
305 'title' => esc_html__( 'Start', 'uicore-elements' ),
306 'icon' => 'eicon-align-start-v',
307 ],
308 'center' => [
309 'title' => esc_html__( 'Center', 'uicore-elements' ),
310 'icon' => 'eicon-align-center-v',
311 ],
312 'end' => [
313 'title' => esc_html__( 'End', 'uicore-elements' ),
314 'icon' => 'eicon-align-end-v',
315 ],
316 'stretch' => [
317 'title' => esc_html__( 'Stretch', 'uicore-elements' ),
318 'icon' => 'eicon-align-stretch-v',
319 ],
320 ],
321 'selectors_dictionary' => [
322 'start' => 'justify-content: flex-start; --ui-e-tabs-title-height: initial; --ui-e-tabs-title-justify-content: initial; --ui-e-tabs-heading-wrap: wrap; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-grow: 0;',
323 'center' => 'justify-content: center; --ui-e-tabs-title-height: initial; --ui-e-tabs-title-justify-content: initial; --ui-e-tabs-heading-wrap: wrap; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-grow: 0;',
324 'end' => 'justify-content: flex-end; --ui-e-tabs-title-height: initial; --ui-e-tabs-title-justify-content: initial; --ui-e-tabs-heading-wrap: wrap; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-grow: 0;',
325 'stretch' => 'justify-content: flex-start; --ui-e-tabs-title-height: 100%; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-heading-wrap: nowrap; --ui-e-tabs-title-flex-basis: auto; --ui-e-tabs-title-flex-grow: 1;',
326 ],
327 'selectors' => [
328 '{{WRAPPER}} .ui-e-tabs-heading' => '{{VALUE}}',
329 ],
330 'condition' => [
331 'tabs_direction' => [
332 'inline-start',
333 'inline-end',
334 ],
335 ],
336 ] );
337
338 $styling_icon_above = '--ui-e-tabs-title-direction: column; --ui-e-tabs-icon-order: initial;';
339 $styling_icon_before = '--ui-e-tabs-title-direction: row; --ui-e-tabs-icon-order: initial';
340 $styling_icon_after = '--ui-e-tabs-title-direction: row; --ui-e-tabs-icon-order: 1;';
341
342 $this->add_responsive_control( 'icon_position', [
343 'label' => esc_html__( 'Icon Position', 'uicore-elements' ),
344 'type' => Controls_Manager::CHOOSE,
345 'options' => [
346 'above' => [
347 'title' => esc_html__( 'Before', 'uicore-elements' ),
348 'icon' => 'eicon-v-align-top',
349 ],
350 'before' => [
351 'title' => esc_html__( 'Before', 'uicore-elements' ),
352 'icon' => 'eicon-h-align-' . $start,
353 ],
354 'after' => [
355 'title' => esc_html__( 'After', 'uicore-elements' ),
356 'icon' => 'eicon-h-align-' . $end,
357 ],
358 ],
359 'default' => 'before',
360 'selectors_dictionary' => [
361 'above' => $styling_icon_above,
362 'before' => $styling_icon_before,
363 'after' => $styling_icon_after,
364 ],
365 'separator' => 'before',
366 'selectors' => [
367 '{{WRAPPER}}' => '{{VALUE}}',
368 ],
369 ] );
370
371 $this->add_responsive_control( 'title_alignment', [
372 'label' => esc_html__( 'Content Alignment', 'uicore-elements' ),
373 'type' => Controls_Manager::CHOOSE,
374 'options' => [
375 'start' => [
376 'title' => esc_html__( 'Start', 'uicore-elements' ),
377 'icon' => 'eicon-text-align-left',
378 ],
379 'center' => [
380 'title' => esc_html__( 'Center', 'uicore-elements' ),
381 'icon' => 'eicon-text-align-center',
382 ],
383 'end' => [
384 'title' => esc_html__( 'End', 'uicore-elements' ),
385 'icon' => 'eicon-text-align-right',
386 ],
387 'justify' => [
388 'title' => esc_html__( 'Justify', 'uicore-elements' ),
389 'icon' => 'eicon-text-align-justify',
390 ],
391 ],
392 'selectors_dictionary' => [
393 'start' => '--ui-e-tabs-title-justify: flex-start; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: start;',
394 'center' => '--ui-e-tabs-title-justify: center; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: center;',
395 'end' => '--ui-e-tabs-title-justify: flex-end; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: end;',
396 'justify' => '--ui-e-tabs-title-justify: space-between; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: start;',
397 ],
398 'condition' => [
399 'icon_position!' => 'above',
400 ],
401 'selectors' => [
402 '{{WRAPPER}}' => '{{VALUE}}',
403 ],
404 ] );
405
406 $this->add_responsive_control( 'title_alignment_above', [
407 'label' => esc_html__( 'Content Alignment', 'uicore-elements' ),
408 'type' => Controls_Manager::CHOOSE,
409 'options' => [
410 'start' => [
411 'title' => esc_html__( 'Start', 'uicore-elements' ),
412 'icon' => 'eicon-text-align-left',
413 ],
414 'center' => [
415 'title' => esc_html__( 'Center', 'uicore-elements' ),
416 'icon' => 'eicon-text-align-center',
417 ],
418 'end' => [
419 'title' => esc_html__( 'End', 'uicore-elements' ),
420 'icon' => 'eicon-text-align-right',
421 ],
422 ],
423 'selectors_dictionary' => [
424 'start' => '--ui-e-tabs-title-justify: flex-start; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: start;',
425 'center' => '--ui-e-tabs-title-justify: flex-start; --ui-e-tabs-title-align: center; --ui-e-tabs-title-text-align: center;',
426 'end' => '--ui-e-tabs-title-justify: flex-start; --ui-e-tabs-title-align: flex-end; --ui-e-tabs-title-text-align: end;',
427 ],
428 'condition' => [
429 'icon_position' => 'above',
430 ],
431 'selectors' => [
432 '{{WRAPPER}}' => '{{VALUE}}',
433 ],
434 ] );
435
436 $this->end_controls_section();
437
438 $this->start_controls_section(
439 'section_tabs_responsive',
440 [
441 'label' => esc_html__( 'Additional Settings', 'uicore-elements' ),
442 ]
443 );
444
445 // Build breakpoint options
446 $dropdown_options = [
447 'none' => esc_html__( 'None', 'uicore-elements' ),
448 ];
449 $excluded_breakpoints = [
450 'laptop',
451 'tablet_extra',
452 'widescreen',
453 ];
454
455 foreach ( Plugin::$instance->breakpoints->get_active_breakpoints() as $breakpoint_key => $breakpoint_instance ) {
456 // Exclude the larger breakpoints from the dropdown selector.
457 if ( in_array( $breakpoint_key, $excluded_breakpoints, true ) ) {
458 continue;
459 }
460
461 $dropdown_options[ $breakpoint_key ] = sprintf(
462 /* translators: 1: Breakpoint label, 2: `>` character, 3: Breakpoint value. */
463 esc_html__( '%1$s (%2$s %3$dpx)', 'uicore-elements' ),
464 $breakpoint_instance->get_label(),
465 '>',
466 $breakpoint_instance->get_value()
467 );
468 }
469
470 $this->add_control(
471 'breakpoint_selector',
472 [
473 'label' => esc_html__( 'Breakpoint', 'uicore-elements' ),
474 'type' => Controls_Manager::SELECT,
475 'description' => esc_html__( 'Note: Choose the breakpoint where tabs automatically switch to a vertical (“accordion”) layout.', 'uicore-elements' ),
476 'options' => $dropdown_options,
477 'default' => 'mobile',
478 'prefix_class' => 'ui-e-tabs-',
479 ]
480 );
481
482 $this->add_control(
483 'show_description',
484 [
485 'label' => esc_html__( 'Toggle Description', 'uicore-elements' ),
486 'type' => Controls_Manager::SWITCHER,
487 'label_on' => esc_html__( 'Show', 'uicore-elements' ),
488 'label_off' => esc_html__( 'Hide', 'uicore-elements' ),
489 'description' => esc_html__('Show descriptions only for active items.', 'uicore-elements'),
490 'return_value' => 'yes',
491 ]
492 );
493
494 $this->end_controls_section();
495
496 $this->start_controls_section(
497 'section_tabs_style',
498 [
499 'label' => esc_html__( 'Tabs', 'uicore-elements' ),
500 'tab' => Controls_Manager::TAB_STYLE,
501 ]
502 );
503
504 $this->add_responsive_control( 'tabs_title_space_between', [
505 'label' => esc_html__( 'Gap between tabs', 'uicore-elements' ),
506 'type' => Controls_Manager::SLIDER,
507 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
508 'range' => [
509 'px' => [
510 'max' => 100,
511 ],
512 'em' => [
513 'max' => 40,
514 ],
515 'rem' => [
516 'max' => 40,
517 ],
518 ],
519 'default' => [
520 'size' => 10,
521 'unit' => 'px',
522 ],
523 'selectors' => [
524 '{{WRAPPER}}' => '--ui-e-tabs-title-gap: {{SIZE}}{{UNIT}}',
525 ],
526 ] );
527
528 $this->add_responsive_control( 'tabs_title_spacing', [
529 'label' => esc_html__( 'Distance from content', 'uicore-elements' ),
530 'type' => Controls_Manager::SLIDER,
531 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
532 'range' => [
533 'px' => [
534 'max' => 100,
535 ],
536 'em' => [
537 'max' => 40,
538 ],
539 'rem' => [
540 'max' => 40,
541 ],
542 ],
543 'selectors' => [
544 '{{WRAPPER}}' => '--ui-e-tabs-gap: {{SIZE}}{{UNIT}}',
545 ],
546 ] );
547
548 $this->start_controls_tabs( 'tabs_title_style' );
549
550 $this->start_controls_tab(
551 'tabs_title_normal',
552 [
553 'label' => esc_html__( 'Normal', 'uicore-elements' ),
554 ]
555 );
556
557 $this->add_group_control(
558 Group_Control_Background::get_type(),
559 [
560 'name' => 'tabs_title_background_color',
561 'types' => [ 'classic', 'gradient' ],
562 'exclude' => [ 'image' ],
563 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]",
564 'fields_options' => [
565 'color' => [
566 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
567 'selectors' => [
568 '{{SELECTOR}}' => 'background: {{VALUE}}',
569 ],
570 ],
571 ],
572 ]
573 );
574
575 $this->add_group_control(
576 Group_Control_Border::get_type(),
577 [
578 'name' => 'tabs_title_border',
579 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]",
580 'fields_options' => [
581 'color' => [
582 'label' => esc_html__( 'Border Color', 'uicore-elements' ),
583 ],
584 'width' => [
585 'label' => esc_html__( 'Border Width', 'uicore-elements' ),
586 ],
587 ],
588 ]
589 );
590
591 $this->add_group_control(
592 Group_Control_Box_Shadow::get_type(),
593 [
594 'name' => 'tabs_title_box_shadow',
595 'label' => esc_html__( 'Shadow', 'uicore-elements' ),
596 'separator' => 'after',
597 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]",
598 ]
599 );
600
601 $this->end_controls_tab();
602
603 $this->start_controls_tab(
604 'tabs_title_hover',
605 [
606 'label' => esc_html__( 'Hover', 'uicore-elements' ),
607 ]
608 );
609
610 $this->add_group_control(
611 Group_Control_Background::get_type(),
612 [
613 'name' => 'tabs_title_background_color_hover',
614 'types' => [ 'classic', 'gradient' ],
615 'exclude' => [ 'image' ],
616 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover",
617 'fields_options' => [
618 'background' => [
619 'default' => 'classic',
620 ],
621 'color' => [
622 'global' => [
623 'default' => Global_Colors::COLOR_ACCENT,
624 ],
625 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
626 'selectors' => [
627 '{{SELECTOR}}' => 'background: {{VALUE}};',
628 ],
629 ],
630 ],
631 ]
632 );
633
634 $this->add_group_control(
635 Group_Control_Border::get_type(),
636 [
637 'name' => 'tabs_title_border_hover',
638 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover",
639 'fields_options' => [
640 'color' => [
641 'label' => esc_html__( 'Border Color', 'uicore-elements' ),
642 ],
643 'width' => [
644 'label' => esc_html__( 'Border Width', 'uicore-elements' ),
645 ],
646 ],
647 ]
648 );
649
650 $this->add_group_control(
651 Group_Control_Box_Shadow::get_type(),
652 [
653 'name' => 'tabs_title_box_shadow_hover',
654 'label' => esc_html__( 'Shadow', 'uicore-elements' ),
655 'separator' => 'after',
656 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover",
657 ]
658 );
659
660 $this->add_control(
661 'hover_animation',
662 [
663 'label' => esc_html__( 'Hover Animation', 'uicore-elements' ),
664 'type' => Controls_Manager::HOVER_ANIMATION,
665 ]
666 );
667
668 $this->add_control(
669 'tabs_title_transition_duration',
670 [
671 'label' => esc_html__( 'Transition Duration', 'uicore-elements' ) . ' (s)',
672 'type' => Controls_Manager::SLIDER,
673 'selectors' => [
674 '{{WRAPPER}}' => '--ui-e-tabs-title-transition: {{SIZE}}s',
675 ],
676 'range' => [
677 'px' => [
678 'min' => 0,
679 'max' => 3,
680 'step' => 0.1,
681 ],
682 ],
683 ]
684 );
685
686 $this->end_controls_tab();
687
688 $this->start_controls_tab(
689 'tabs_title_active',
690 [
691 'label' => esc_html__( 'Active', 'uicore-elements' ),
692 ]
693 );
694
695 $this->add_group_control(
696 Group_Control_Background::get_type(),
697 [
698 'name' => 'tabs_title_background_color_active',
699 'types' => [ 'classic', 'gradient' ],
700 'exclude' => [ 'image' ],
701 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"]",
702 'fields_options' => [
703 'background' => [
704 'default' => 'classic',
705 ],
706 'color' => [
707 'global' => [
708 'default' => Global_Colors::COLOR_ACCENT,
709 ],
710 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
711 'selectors' => [
712 '{{SELECTOR}}' => 'background: {{VALUE}};',
713 ],
714 ],
715 ],
716 ]
717 );
718
719 $this->add_group_control(
720 Group_Control_Border::get_type(),
721 [
722 'name' => 'tabs_title_border_active',
723 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"]",
724 'fields_options' => [
725 'color' => [
726 'label' => esc_html__( 'Border Color', 'uicore-elements' ),
727 ],
728 'width' => [
729 'label' => esc_html__( 'Border Width', 'uicore-elements' ),
730 ],
731 ],
732 ]
733 );
734
735 $this->add_group_control(
736 Group_Control_Box_Shadow::get_type(),
737 [
738 'name' => 'tabs_title_box_shadow_active',
739 'label' => esc_html__( 'Shadow', 'uicore-elements' ),
740 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"]",
741 ]
742 );
743
744 $this->end_controls_tab();
745
746 $this->end_controls_tabs();
747
748 $this->add_control(
749 'tabs_pill',
750 [
751 'label' => esc_html__( 'Pill Style', 'uicore-elements' ),
752 'type' => Controls_Manager::SWITCHER,
753 'return_value' => 'yes',
754 'prefix_class' => 'ui-e-pill-tabs-',
755 'separator' => 'before',
756 'device_args' => [
757 'desktop' => [
758 'condition' => [
759 'tabs_direction' => ['block-start', 'block-end'],
760 ],
761 ],
762 'mobile' => [
763 'condition' => [
764 'tabs_direction' => ['block-start', 'block-end'],
765 ]
766 ],
767 'tablet' => [
768 'condition' => [
769 'tabs_direction' => ['block-start', 'block-end'],
770 ]
771 ]
772 ],
773 ]
774 );
775
776 $this->add_responsive_control(
777 'tabs_title_border_radius',
778 [
779 'label' => esc_html__( 'Border Radius', 'uicore-elements' ),
780 'type' => Controls_Manager::DIMENSIONS,
781 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
782 'selectors' => [
783 "{$heading_selector}" => '--ui-e-tab-border-top: {{TOP}}{{UNIT}}; --ui-e-tab-border-right: {{RIGHT}}{{UNIT}}; --ui-e-tab-border-bot: {{BOTTOM}}{{UNIT}}; --ui-e-tab-border-left: {{LEFT}}{{UNIT}};',
784 ],
785 ]
786 );
787
788 $this->add_responsive_control(
789 'padding',
790 [
791 'label' => esc_html__( 'Padding', 'uicore-elements' ),
792 'type' => Controls_Manager::DIMENSIONS,
793 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
794 'selectors' => [
795 "{$heading_selector} > .ui-e-tab-title" => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
796 ],
797 ]
798 );
799
800 $this->end_controls_section();
801
802 $this->start_controls_section(
803 'section_title_style',
804 [
805 'label' => esc_html__( 'Titles', 'uicore-elements' ),
806 'tab' => Controls_Manager::TAB_STYLE,
807 ]
808 );
809
810 $this->add_group_control( Group_Control_Typography::get_type(), [
811 'name' => 'title_typography',
812 'global' => [
813 'default' => Global_Typography::TYPOGRAPHY_ACCENT,
814 ],
815 'selector' => "{$heading_selector} .ui-e-tab-texts span",
816 ] );
817
818 $this->start_controls_tabs( 'title_style' );
819
820 $this->start_controls_tab(
821 'title_normal',
822 [
823 'label' => esc_html__( 'Normal', 'uicore-elements' ),
824 ]
825 );
826
827 $this->add_control(
828 'title_text_color',
829 [
830 'label' => esc_html__( 'Color', 'uicore-elements' ),
831 'type' => Controls_Manager::COLOR,
832 'selectors' => [
833 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"] .ui-e-tab-texts > span" => 'color: {{VALUE}}',
834 ],
835 ]
836 );
837
838 $this->end_controls_tab();
839
840 $this->start_controls_tab(
841 'title_hover',
842 [
843 'label' => esc_html__( 'Hover', 'uicore-elements' ),
844 ]
845 );
846
847 $this->add_control(
848 'title_text_color_hover',
849 [
850 'label' => esc_html__( 'Color', 'uicore-elements' ),
851 'type' => Controls_Manager::COLOR,
852 'selectors' => [
853 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover .ui-e-tab-texts > span" => 'color: {{VALUE}}',
854 ],
855 ]
856 );
857
858 $this->end_controls_tab();
859
860 $this->start_controls_tab(
861 'title_active',
862 [
863 'label' => esc_html__( 'Active', 'uicore-elements' ),
864 ]
865 );
866
867 $this->add_control(
868 'title_text_color_active',
869 [
870 'label' => esc_html__( 'Color', 'uicore-elements' ),
871 'type' => Controls_Manager::COLOR,
872 'selectors' => [
873 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"] .ui-e-tab-texts > span" => 'color: {{VALUE}}',
874 ],
875 ]
876 );
877
878 $this->end_controls_tab();
879
880 $this->end_controls_tabs();
881
882 $this->end_controls_section();
883
884 $this->start_controls_section(
885 'section_description_style',
886 [
887 'label' => esc_html__( 'Description', 'uicore-elements' ),
888 'tab' => Controls_Manager::TAB_STYLE,
889 ]
890 );
891
892 $this->add_group_control( Group_Control_Typography::get_type(), [
893 'name' => 'description_typography',
894 'global' => [
895 'default' => Global_Typography::TYPOGRAPHY_ACCENT,
896 ],
897 'selector' => "{$heading_selector} .ui-e-tab-texts p",
898 ] );
899
900 $this->add_responsive_control(
901 'description_spacing',
902 [
903 'label' => esc_html__( 'Top Spacing', 'uicore-elements' ),
904 'type' => Controls_Manager::SLIDER,
905 'range' => [
906 'px' => [
907 'max' => 50,
908 ],
909 '%' => [
910 'max' => 50,
911 'step' => 0.1,
912 ],
913 ],
914 'default' => [
915 'size' => 0,
916 'unit' => 'px',
917 ],
918 'size_units' => [ 'px', 'em', 'rem', '%'],
919 'selectors' => [
920 "{$heading_selector} .ui-e-tab-texts > p" => 'margin-top: {{SIZE}}{{UNIT}}',
921 ],
922 ]
923 );
924
925 $this->start_controls_tabs( 'description_style' );
926
927 $this->start_controls_tab(
928 'description_normal',
929 [
930 'label' => esc_html__( 'Normal', 'uicore-elements' ),
931 ]
932 );
933
934 $this->add_control(
935 'description_text_color',
936 [
937 'label' => esc_html__( 'Color', 'uicore-elements' ),
938 'type' => Controls_Manager::COLOR,
939 'selectors' => [
940 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"] .ui-e-tab-texts > p" => 'color: {{VALUE}}',
941 ],
942 ]
943 );
944
945 $this->end_controls_tab();
946
947 $this->start_controls_tab(
948 'description_hover',
949 [
950 'label' => esc_html__( 'Hover', 'uicore-elements' ),
951 ]
952 );
953
954 $this->add_control(
955 'description_text_color_hover',
956 [
957 'label' => esc_html__( 'Color', 'uicore-elements' ),
958 'type' => Controls_Manager::COLOR,
959 'selectors' => [
960 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover .ui-e-tab-texts > p" => 'color: {{VALUE}}',
961 ],
962 ]
963 );
964
965 $this->end_controls_tab();
966
967 $this->start_controls_tab(
968 'description_active',
969 [
970 'label' => esc_html__( 'Active', 'uicore-elements' ),
971 ]
972 );
973
974 $this->add_control(
975 'description_text_color_active',
976 [
977 'label' => esc_html__( 'Color', 'uicore-elements' ),
978 'type' => Controls_Manager::COLOR,
979 'selectors' => [
980 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"] .ui-e-tab-texts > p" => 'color: {{VALUE}}',
981 ],
982 ]
983 );
984
985 $this->end_controls_tab();
986
987 $this->end_controls_tabs();
988
989 $this->end_controls_section();
990
991 $this->start_controls_section(
992 'icon_section_style',
993 [
994 'label' => esc_html__( 'Icon', 'uicore-elements' ),
995 'tab' => Controls_Manager::TAB_STYLE,
996 ]
997 );
998
999 $this->add_responsive_control( 'icon_size', [
1000 'label' => esc_html__( 'Size', 'uicore-elements' ),
1001 'type' => Controls_Manager::SLIDER,
1002 'range' => [
1003 'px' => [
1004 'max' => 100,
1005 ],
1006 'em' => [
1007 'max' => 10,
1008 ],
1009 'rem' => [
1010 'max' => 10,
1011 ],
1012 ],
1013 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ],
1014 'selectors' => [
1015 '{{WRAPPER}}' => '--ui-e-tabs-icon-size: {{SIZE}}{{UNIT}}',
1016 ],
1017 ] );
1018
1019 $this->add_responsive_control( 'icon_spacing', [
1020 'label' => esc_html__( 'Spacing', 'uicore-elements' ),
1021 'type' => Controls_Manager::SLIDER,
1022 'range' => [
1023 'px' => [
1024 'max' => 200,
1025 ],
1026 'vw' => [
1027 'max' => 50,
1028 'step' => 0.1,
1029 ],
1030 ],
1031 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ],
1032 'selectors' => [
1033 '{{WRAPPER}} .ui-e-tab-title' => 'gap: {{SIZE}}{{UNIT}}',
1034 ],
1035 ] );
1036
1037 $this->add_control(
1038 'icon_padding',
1039 [
1040 'label' => esc_html__( 'Padding', 'uicore-elements' ),
1041 'type' => Controls_Manager::DIMENSIONS,
1042 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
1043 'selectors' => [
1044 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1045 ],
1046 ]
1047 );
1048
1049 $this->add_control(
1050 'icon_border_radius',
1051 [
1052 'label' => esc_html__( 'Border Radius', 'uicore-elements' ),
1053 'type' => Controls_Manager::DIMENSIONS,
1054 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
1055 'selectors' => [
1056 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1057 ],
1058 ]
1059 );
1060
1061 $this->add_group_control(
1062 Group_Control_Border::get_type(),
1063 [
1064 'name' => 'icon_border',
1065 'selector' => '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon',
1066 ]
1067 );
1068
1069 $this->start_controls_tabs( 'icon_style_states' );
1070
1071 $this->start_controls_tab(
1072 'icon_section_normal',
1073 [
1074 'label' => esc_html__( 'Normal', 'uicore-elements' ),
1075 ]
1076 );
1077
1078 $this->add_control( 'icon_color', [
1079 'label' => esc_html__( 'Color', 'uicore-elements' ),
1080 'type' => Controls_Manager::COLOR,
1081 'selectors' => [
1082 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon > i' => 'color: {{VALUE}}',
1083 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon > svg' => 'fill: {{VALUE}}',
1084 ],
1085 ] );
1086
1087 $this->add_control(
1088 'icon_background_color',
1089 [
1090 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
1091 'type' => Controls_Manager::COLOR,
1092 'selectors' => [
1093 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon' => 'background-color: {{VALUE}}',
1094 ],
1095 ]
1096 );
1097
1098 $this->end_controls_tab();
1099
1100 $this->start_controls_tab(
1101 'icon_section_hover',
1102 [
1103 'label' => esc_html__( 'Hover', 'uicore-elements' ),
1104 ]
1105 );
1106
1107 $this->add_control( 'icon_color_hover', [
1108 'label' => esc_html__( 'Color', 'uicore-elements' ),
1109 'type' => Controls_Manager::COLOR,
1110 'selectors' => [
1111 '{{WRAPPER}} .ui-e-tab-title:hover .ui-e-tab-icon > i' => 'color: {{VALUE}}',
1112 '{{WRAPPER}} .ui-e-tab-title:hover .ui-e-tab-icon > svg' => 'fill: {{VALUE}}',
1113 ],
1114 ] );
1115
1116 $this->add_control(
1117 'icon_background_color_hover',
1118 [
1119 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
1120 'type' => Controls_Manager::COLOR,
1121 'selectors' => [
1122 '{{WRAPPER}} .ui-e-tab-title:hover .ui-e-tab-icon' => 'background-color: {{VALUE}}',
1123 ],
1124 ]
1125 );
1126
1127 $this->end_controls_tab();
1128
1129 $this->start_controls_tab(
1130 'icon_section_active',
1131 [
1132 'label' => esc_html__( 'Active', 'uicore-elements' ),
1133 ]
1134 );
1135
1136 $this->add_control( 'icon_color_active', [
1137 'label' => esc_html__( 'Color', 'uicore-elements' ),
1138 'type' => Controls_Manager::COLOR,
1139 'selectors' => [
1140 '{{WRAPPER}} .ui-e-tab-title[aria-selected="true"] .ui-e-tab-icon > i' => 'color: {{VALUE}}',
1141 '{{WRAPPER}} .ui-e-tab-title[aria-selected="true"] .ui-e-tab-icon > svg' => 'fill: {{VALUE}}',
1142 ],
1143 ] );
1144
1145 $this->add_control(
1146 'icon_background_color_active',
1147 [
1148 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
1149 'type' => Controls_Manager::COLOR,
1150 'selectors' => [
1151 '{{WRAPPER}} .ui-e-tab-title[aria-selected="true"] .ui-e-tab-icon' => 'background-color: {{VALUE}}',
1152 ],
1153 ]
1154 );
1155
1156 $this->end_controls_tab();
1157
1158 $this->end_controls_tabs();
1159
1160 $this->end_controls_section();
1161
1162 $this->start_controls_section( 'section_box_style', [
1163 'label' => esc_html__( 'Content', 'uicore-elements' ),
1164 'tab' => Controls_Manager::TAB_STYLE,
1165 ] );
1166
1167 $this->add_group_control(
1168 Group_Control_Background::get_type(),
1169 [
1170 'name' => 'box_background_color',
1171 'types' => [ 'classic', 'gradient' ],
1172 'exclude' => [ 'image' ],
1173 'selector' => $content_selector,
1174 'fields_options' => [
1175 'color' => [
1176 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
1177 ],
1178 ],
1179 ]
1180 );
1181
1182 $this->add_group_control(
1183 Group_Control_Border::get_type(),
1184 [
1185 'name' => 'box_border',
1186 'selector' => $content_selector,
1187 'fields_options' => [
1188 'color' => [
1189 'label' => esc_html__( 'Border Color', 'uicore-elements' ),
1190 ],
1191 'width' => [
1192 'label' => esc_html__( 'Border Width', 'uicore-elements' ),
1193 ],
1194 ],
1195 ]
1196 );
1197
1198 $this->add_responsive_control(
1199 'box_border_radius',
1200 [
1201 'label' => esc_html__( 'Border Radius', 'uicore-elements' ),
1202 'type' => Controls_Manager::DIMENSIONS,
1203 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
1204 'selectors' => [
1205 $content_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1206 ],
1207 ]
1208 );
1209
1210 $this->add_group_control(
1211 Group_Control_Box_Shadow::get_type(),
1212 [
1213 'name' => 'box_shadow_box_shadow',
1214 'selector' => $content_selector,
1215 ]
1216 );
1217
1218 $this->add_responsive_control(
1219 'box_padding',
1220 [
1221 'label' => esc_html__( 'Padding', 'uicore-elements' ),
1222 'type' => Controls_Manager::DIMENSIONS,
1223 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
1224 'selectors' => [
1225 $content_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1226 ],
1227 ]
1228 );
1229
1230 $this->end_controls_section();
1231
1232 }
1233
1234 protected function maybe_render_tab_icons_html( $item_settings ): void {
1235 $icon_settings = $item_settings['item']['tab_icon'];
1236
1237 if ( empty( $icon_settings['value'] ) ) {
1238 return;
1239 }
1240
1241 $active_icon_settings = $this->is_active_icon_exist( $item_settings['item'] )
1242 ? $item_settings['item']['tab_icon_active']
1243 : $icon_settings;
1244 ?>
1245 <span <?php $this->print_render_attribute_string( 'tab-icon' ); ?>>
1246 <?php Icons_Manager::render_icon( $active_icon_settings, [ 'aria-hidden' => 'true' ] ); ?>
1247 <?php Icons_Manager::render_icon( $icon_settings, [ 'aria-hidden' => 'true' ] ); ?>
1248 </span>
1249 <?php
1250 }
1251
1252 protected function render_tab_titles_html( $item_settings ): string {
1253 // Data
1254 $setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $item_settings['index'] );
1255 $title = $item_settings['item']['tab_title'];
1256 $description = $item_settings['item']['tab_description'];
1257 // Classes
1258 $hover_animation = $item_settings['hover_animation'] ? 'elementor-animation-' . $item_settings['hover_animation'] : '';
1259 $toggle_description = $item_settings['show_description'] ? 'ui-e-toggle-description' : '';
1260
1261 $this->add_render_attribute( $setting_key, [
1262 'id' => $item_settings['tab_id'],
1263 'class' => [
1264 'ui-e-tab-title',
1265 $toggle_description,
1266 $hover_animation
1267 ],
1268 'aria-selected' => (1 === (int)$item_settings['tab_count'] ? 'true' : 'false'),
1269 'data-tab-index' => $item_settings['tab_count'],
1270 'role' => 'tab',
1271 'tabindex' => (1 === $item_settings['tab_count'] ? '0' : '-1'),
1272 'aria-controls' => $item_settings['container_id'],
1273 'style' => '--ui-e-tabs-order: ' . $item_settings['tab_count'] . ';',
1274 ] );
1275
1276 $render_attributes = $this->get_render_attribute_string( $setting_key );
1277 $text_class = $this->get_render_attribute_string( 'tab-texts' );
1278
1279 ob_start();
1280 ?>
1281 <button <?php echo $render_attributes; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1282 <?php $this->maybe_render_tab_icons_html( $item_settings ); ?>
1283 <div <?php echo $text_class; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1284
1285 <?php if( !empty( $title ) ) : ?>
1286 <span> <?php echo wp_kses_post( $title ); ?> </span>
1287 <?php endif; ?>
1288
1289 <?php if( !empty( $description ) ) : ?>
1290 <p> <?php echo wp_kses_post( $description ); ?> </p>
1291 <?php endif; ?>
1292
1293 </div>
1294 </button>
1295 <?php
1296 return ob_get_clean();
1297 }
1298
1299 protected function render_tab_containers_html( $item_settings ): string {
1300 ob_start();
1301 $this->print_child( $item_settings['index'], $item_settings );
1302 return ob_get_clean();
1303 }
1304
1305 private function is_active_icon_exist( $item ) {
1306 return array_key_exists( 'tab_icon_active', $item ) && ! empty( $item['tab_icon_active'] ) && ! empty( $item['tab_icon_active']['value'] );
1307 }
1308
1309 /**
1310 * Print the content area.
1311 *
1312 * @param int $index
1313 * @param array $item_settings
1314 */
1315 public function print_child( $index, $item_settings = [] ) {
1316 $children = $this->get_children();
1317 $child_ids = [];
1318 if( empty( $children )){
1319 return;
1320 }
1321 foreach ( $children as $child ) {
1322 $child_ids[] = $child->get_id();
1323 }
1324
1325 // Add data-tab-index attribute to the content area.
1326 $add_attribute_to_container = function ( $should_render, $container ) use ( $item_settings, $child_ids ) {
1327 if ( in_array( $container->get_id(), $child_ids ) ) {
1328 $this->add_attributes_to_container( $container, $item_settings );
1329 }
1330
1331 return $should_render;
1332 };
1333
1334 add_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container, 10, 3 );
1335 $children[ $index ]->print_element();
1336 remove_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container );
1337 }
1338
1339 protected function add_attributes_to_container( $container, $item_settings ) {
1340 $container->add_render_attribute( '_wrapper', [
1341 'id' => $item_settings['container_id'],
1342 'role' => 'tabpanel',
1343 'aria-labelledby' => $item_settings['tab_id'],
1344 'data-tab-index' => $item_settings['tab_count'],
1345 'style' => '--ui-e-tabs-order: ' . $item_settings['tab_count'] . ';',
1346 'class' => 0 === $item_settings['index'] ? 'e-active' : '',
1347 ] );
1348 }
1349
1350 protected function render() {
1351
1352 if( Plugin::$instance->experiments->is_feature_active('nested-elements') == false ){
1353 $this->nesting_fallback();
1354 return;
1355 }
1356
1357 $settings = $this->get_settings_for_display();
1358 $widget_number = substr( $this->get_id_int(), 0, 3 );
1359
1360 $this->add_render_attribute( 'elementor-tabs', [
1361 'class' => 'ui-e-tabs',
1362 'data-widget-number' => $widget_number,
1363 'aria-label' => esc_html__( 'Tabs. Open items with Enter or Space, close with Escape and navigate using the Arrow keys.', 'uicore-elements' ),
1364 ] );
1365
1366 $this->add_render_attribute( 'tab-texts', 'class', 'ui-e-tab-texts' );
1367 $this->add_render_attribute( 'tab-icon', 'class', 'ui-e-tab-icon' );
1368 $this->add_render_attribute( 'tab-icon-active', 'class', [ 'ui-e-tab-icon' ] );
1369
1370 $tab_titles_html = '';
1371 $tab_containers_html = '';
1372
1373 foreach ( $settings['tabs'] as $index => $item ) {
1374 $tab_count = $index + 1;
1375
1376 $tab_id = empty( $item['tab_id'] )
1377 ? 'ui-e-tab-title-' . $widget_number . $tab_count
1378 : $item['tab_id'];
1379
1380 $item_settings = [
1381 'index' => $index,
1382 'tab_count' => $tab_count,
1383 'tab_id' => $tab_id,
1384 'container_id' => 'ui-e-tab-content-' . $widget_number . $tab_count,
1385 'widget_number' => $widget_number,
1386 'hover_animation' => $settings['hover_animation'],
1387 'show_description' => $settings['show_description'],
1388 'item' => $item,
1389 'settings' => $settings,
1390 ];
1391
1392 $tab_titles_html .= $this->render_tab_titles_html( $item_settings );
1393 $tab_containers_html .= $this->render_tab_containers_html( $item_settings );
1394 }
1395 ?>
1396 <div <?php $this->print_render_attribute_string( 'elementor-tabs' ); ?>>
1397 <div class="ui-e-tabs-heading" role="tablist">
1398 <?php echo $tab_titles_html;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1399 </div>
1400 <div class="ui-e-tabs-content">
1401 <?php echo $tab_containers_html;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1402 </div>
1403 </div>
1404 <?php
1405 }
1406
1407 protected function get_initial_config(): array {
1408 if ( Plugin::$instance->experiments->is_feature_active( 'e_nested_atomic_repeaters' ) ) {
1409 return array_merge( parent::get_initial_config(), [
1410 'support_improved_repeaters' => true,
1411 'target_container' => [ '.ui-e-tabs-heading' ],
1412 'node' => 'button',
1413 ] );
1414 }
1415
1416 return parent::get_initial_config();
1417 }
1418 /*
1419 protected function content_template_single_repeater_item() {
1420 ?>
1421 <#
1422 const tabCount = view.collection.length + 1,
1423 elementUid = view.getIDInt().toString().substring( 0, 3 ) + tabCount,
1424 tabIcon = elementor.helpers.renderIcon( view, data.tab_icon, { 'aria-hidden': true }, 'i' , 'object' );
1425
1426 let tabActiveIcon = tabIcon,
1427 tabId = 'ui-e-tab-title-' + elementUid;
1428
1429 if ( '' !== data.tab_icon_active.value ) {
1430 tabActiveIcon = elementor.helpers.renderIcon( view, data.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' );
1431 }
1432
1433 const tabWrapperKey = {
1434 'id': 'ui-e-tab-title-' + elementUid,
1435 'class': [ 'ui-e-tab-title' ],
1436 'data-tab-index': tabCount,
1437 'role': 'tab',
1438 'aria-selected': 1 === tabCount ? 'true' : 'false',
1439 'tabindex': 1 === tabCount ? '0' : '-1',
1440 'aria-controls': 'ui-e-tab-content-' + elementUid,
1441 'style': '--ui-e-tabs-order: ' + tabCount + ';',
1442 };
1443
1444 const tabIconKey = {
1445 'class': [ 'ui-e-tab-icon' ],
1446 'data-binding-type': 'repeater-item',
1447 'data-binding-repeater-name': 'tabs',
1448 'data-binding-setting': [ data.tab_icon.value, data.tab_icon_active.value ],
1449 'data-binding-index': tabCount,
1450 };
1451
1452 const tabTitleKey = {
1453 'class': [ 'ui-e-tab-title-text' ],
1454 'data-binding-type': 'repeater-item',
1455 'data-binding-repeater-name': 'tabs',
1456 'data-binding-setting': [ 'tab_title' ],
1457 'data-binding-index': tabCount,
1458 };
1459
1460 view.addRenderAttribute( 'button-container', tabWrapperKey, null, true );
1461 view.addRenderAttribute( 'tab-title-container', tabTitleKey, null, true );
1462 view.addRenderAttribute( 'tab-icon-key-container', tabIconKey, null, true );
1463 #>
1464
1465 <button {{{ view.getRenderAttributeString( 'button-container' ) }}}>
1466 <# if ( tabIcon.value ) { #>
1467 <span {{{ view.getRenderAttributeString( 'tab-icon-key-container' ) }}}> {{{ tabIcon.value }}}{{{ tabActiveIcon.value }}} </span>
1468 <# } #>
1469 <span {{{ view.getRenderAttributeString( 'tab-title-container' ) }}}> {{{ data.tab_title }}} </span>
1470 </button>
1471 <?php
1472 }
1473 */
1474 /*
1475 protected function content_template_single_repeater_item() {
1476 ?>
1477 <#
1478 const tabIndex = view.collection.length,
1479 elementUid = view.getIDInt().toString(),
1480 item = data,
1481 hoverAnimationSetting = view?.container?.settings?.attributes?.hover_animation;
1482 hoverAnimationClass = hoverAnimationSetting
1483 ? `elementor-animation-${ hoverAnimationSetting }`
1484 : '';
1485 #>
1486 <?php $this->content_template_single_item( '{{ tabIndex }}', '{{ item }}', '{{ elementUid }}', '{{ hoverAnimationClass }}' );
1487 }
1488 */
1489 protected function content_template() {
1490
1491 if( Plugin::$instance->experiments->is_feature_active('nested-elements') == false ){
1492 return;
1493 }
1494
1495 ?>
1496 <# const elementUid = view.getIDInt().toString().substr( 0, 3 ); #>
1497 <div class="ui-e-tabs" data-widget-number="{{ elementUid }}" aria-label="<?php echo esc_html__( 'Tabs. Open items with Enter or Space, close with Escape and navigate using the Arrow keys.', 'uicore-elements' ); ?>">
1498 <# if ( settings['tabs'] ) { #>
1499 <div class="ui-e-tabs-heading" role="tablist">
1500 <# _.each( settings['tabs'], function( item, index ) {
1501 const tabCount = index + 1,
1502 tabUid = elementUid + tabCount,
1503 tabWrapperKey = tabUid,
1504 tabTitleKey = 'tab-title-' + tabUid,
1505 tabIconKey = 'tab-icon-' + tabUid,
1506 tabIcon = elementor.helpers.renderIcon( view, item.tab_icon, { 'aria-hidden': true }, 'i' , 'object' ),
1507 hoverAnimationClass = settings['hover_animation'] ? `elementor-animation-${ settings['hover_animation'] }` : '',
1508 showDescription = settings['show_description'] ? 'ui-e-toggle-description' : '';
1509
1510 let tabActiveIcon = tabIcon,
1511 tabId = 'ui-e-tab-title-' + tabUid;
1512
1513 if ( '' !== item.tab_icon_active.value ) {
1514 tabActiveIcon = elementor.helpers.renderIcon( view, item.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' );
1515 }
1516
1517 if ( '' !== item.tab_id ) {
1518 tabId = item.tab_id;
1519 }
1520
1521 view.addRenderAttribute( tabWrapperKey, {
1522 'id': tabId,
1523 'class': [ 'ui-e-tab-title', hoverAnimationClass, showDescription ],
1524 'data-tab-index': tabCount,
1525 'role': 'tab',
1526 'aria-selected': 1 === tabCount ? 'true' : 'false',
1527 'tabindex': 1 === tabCount ? '0' : '-1',
1528 'aria-controls': 'ui-e-tab-content-' + tabUid,
1529 'style': '--ui-e-tabs-order: ' + tabCount + ';',
1530 } );
1531
1532 view.addRenderAttribute( tabTitleKey, {
1533 'class': [ 'ui-e-tab-texts' ],
1534 'data-binding-type': 'repeater-item',
1535 'data-binding-repeater-name': 'tabs',
1536 'data-binding-setting': [ 'tab_title' ],
1537 'data-binding-index': tabCount,
1538 } );
1539
1540 view.addRenderAttribute( tabIconKey, {
1541 'class': [ 'ui-e-tab-icon' ],
1542 'data-binding-type': 'repeater-item',
1543 'data-binding-repeater-name': 'tabs',
1544 'data-binding-setting': [ 'tab_icon.value', 'tab_icon_active.value' ],
1545 'data-binding-index': tabCount,
1546 } );
1547 #>
1548 <button {{{ view.getRenderAttributeString( tabWrapperKey ) }}}>
1549 <# if ( tabIcon.value ) { #>
1550 <span {{{ view.getRenderAttributeString( tabIconKey ) }}}>{{{ tabActiveIcon.value }}}{{{ tabIcon.value }}}</span>
1551 <# } #>
1552 <div {{{ view.getRenderAttributeString( tabTitleKey ) }}}>
1553 <# if ( item.tab_title ) { #>
1554 <span> {{{ item.tab_title }}} </span>
1555 <# } #>
1556 <# if ( item.tab_description ) { #>
1557 <p> {{{ item.tab_description }}} </p>
1558 <# } #>
1559 </div>
1560 </button>
1561 <# } ); #>
1562 </div>
1563 <div class="ui-e-tabs-content"></div>
1564 <# } #>
1565 </div>
1566 <?php
1567 }
1568 /*
1569 private function content_template_single_item( $tab_index, $item, $element_uid, $hover_animation_class ) {
1570 ?>
1571 <#
1572 const tabCount = tabIndex + 1,
1573 tabId = item.tab_id
1574 ? item.tab_id
1575 : 'ui-e-tab-title-' + elementUid + ( tabIndex + 1 ),
1576 tabUid = elementUid + tabCount,
1577 tabIcon = elementor.helpers.renderIcon( view, item.tab_icon, { 'aria-hidden': true }, 'i' , 'object' ),
1578 activeTabIcon = item.tab_icon_active.value
1579 ? elementor.helpers.renderIcon( view, item.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' )
1580 : tabIcon,
1581 escapedHoverAnimationClass = _.escape( hoverAnimationClass );
1582
1583 view.addRenderAttribute( 'tab-title', {
1584 'id': tabId,
1585 'class': [ 'ui-e-tab-title',escapedHoverAnimationClass ],
1586 'data-tab-index': tabCount,
1587 'role': 'tab',
1588 'aria-selected': 1 === tabCount ? 'true' : 'false',
1589 'tabindex': 1 === tabCount ? '0' : '-1',
1590 'aria-controls': 'ui-e-tab-content-' + tabUid,
1591 'style': '--ui-e-tabs-order: ' + tabCount + ';',
1592 }, null, true );
1593
1594 view.addRenderAttribute( 'tab-title-text', {
1595 'class': [ 'ui-e-tab-title-text' ],
1596 'data-binding-type': 'repeater-item',
1597 'data-binding-repeater-name': 'tabs',
1598 'data-binding-setting': [ 'tab_title' ],
1599 'data-binding-index': tabCount,
1600 'data-binding-dynamic': 'true',
1601 }, null, true );
1602
1603 view.addRenderAttribute( 'tab-icon', {
1604 'class': [ 'ui-e-tab-icon' ],
1605 'data-binding-type': 'repeater-item',
1606 'data-binding-repeater-name': 'tabs',
1607 'data-binding-setting': [ 'tab_icon', 'tab_icon_active' ],
1608 'data-binding-index': tabCount,
1609 }, null, true );
1610 #>
1611
1612 <button {{{ view.getRenderAttributeString( 'tab-title' ) }}}>
1613 <# if ( !! item.tab_icon.value ) { #>
1614 <span {{{ view.getRenderAttributeString( 'tab-icon' ) }}}>{{{ tabIcon.value }}}{{{ activeTabIcon.value }}}</span>
1615 <# } #>
1616
1617 <span {{{ view.getRenderAttributeString( 'tab-title-text' ) }}}>{{{ item.tab_title }}}</span>
1618 </button>
1619 <?php
1620 }
1621 */
1622 }
1623 \Elementor\Plugin::instance()->widgets_manager->register(new Tabs());