PluginProbe
Elementor Website Builder – more than just a page builder / 3.23.0-dev6
Elementor Website Builder – more than just a page builder v3.23.0-dev6
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / modules / nested-tabs / widgets / nested-tabs.php

nested-tabs.php in Elementor Website Builder – more than just a page builder 3.23.0-dev6, at modules/nested-tabs/widgets/nested-tabs.php

1,334 lines 39.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Modules\NestedTabs\Widgets;
3
4 use Elementor\Controls_Manager;
5 use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
6 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
7 use Elementor\Group_Control_Background;
8 use Elementor\Group_Control_Border;
9 use Elementor\Group_Control_Box_Shadow;
10 use Elementor\Group_Control_Text_Shadow;
11 use Elementor\Group_Control_Text_Stroke;
12 use Elementor\Group_Control_Typography;
13 use Elementor\Icons_Manager;
14 use Elementor\Modules\NestedElements\Base\Widget_Nested_Base;
15 use Elementor\Modules\NestedElements\Controls\Control_Nested_Repeater;
16 use Elementor\Plugin;
17 use Elementor\Repeater;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit; // Exit if accessed directly
21 }
22
23 class NestedTabs extends Widget_Nested_Base {
24
25 private $tab_item_settings = [];
26
27 public function get_name() {
28 return 'nested-tabs';
29 }
30
31 public function get_title() {
32 return esc_html__( 'Tabs', 'elementor' );
33 }
34
35 public function get_icon() {
36 return 'eicon-tabs';
37 }
38
39 public function get_keywords() {
40 return [ 'nested', 'tabs', 'accordion', 'toggle' ];
41 }
42
43 protected function tab_content_container( int $index ) {
44 return [
45 'elType' => 'container',
46 'settings' => [
47 '_title' => sprintf( __( 'Tab #%s', 'elementor' ), $index ),
48 'content_width' => 'full',
49 ],
50 ];
51 }
52
53 protected function get_default_children_elements() {
54 return [
55 $this->tab_content_container( 1 ),
56 $this->tab_content_container( 2 ),
57 $this->tab_content_container( 3 ),
58 ];
59 }
60
61 protected function get_default_repeater_title_setting_key() {
62 return 'tab_title';
63 }
64
65 protected function get_default_children_title() {
66 return esc_html__( 'Tab #%d', 'elementor' );
67 }
68
69 protected function get_default_children_placeholder_selector() {
70 return '.e-n-tabs-content';
71 }
72
73 protected function get_html_wrapper_class() {
74 return 'elementor-widget-n-tabs';
75 }
76
77 protected function register_controls() {
78 $start = is_rtl() ? 'right' : 'left';
79 $end = is_rtl() ? 'left' : 'right';
80 $start_logical = is_rtl() ? 'end' : 'start';
81 $end_logical = is_rtl() ? 'start' : 'end';
82 $heading_selector_non_touch_device = '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs[data-touch-mode="false"] > .e-n-tabs-heading';
83 $heading_selector_touch_device = '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs[data-touch-mode="true"] > .e-n-tabs-heading';
84 $heading_selector = '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs > .e-n-tabs-heading';
85 $content_selector = ':where( {{WRAPPER}} > .elementor-widget-container > .e-n-tabs > .e-n-tabs-content ) > .e-con';
86
87 $this->start_controls_section( 'section_tabs', [
88 'label' => esc_html__( 'Tabs', 'elementor' ),
89 ] );
90
91 $repeater = new Repeater();
92
93 $repeater->add_control( 'tab_title', [
94 'label' => esc_html__( 'Title', 'elementor' ),
95 'type' => Controls_Manager::TEXT,
96 'default' => esc_html__( 'Tab Title', 'elementor' ),
97 'placeholder' => esc_html__( 'Tab Title', 'elementor' ),
98 'label_block' => true,
99 'dynamic' => [
100 'active' => true,
101 ],
102 ] );
103
104 $repeater->add_control(
105 'tab_icon',
106 [
107 'label' => esc_html__( 'Icon', 'elementor' ),
108 'type' => Controls_Manager::ICONS,
109 'fa4compatibility' => 'icon',
110 'skin' => 'inline',
111 'label_block' => false,
112 ]
113 );
114
115 $repeater->add_control(
116 'tab_icon_active',
117 [
118 'label' => esc_html__( 'Active Icon', 'elementor' ),
119 'type' => Controls_Manager::ICONS,
120 'fa4compatibility' => 'icon',
121 'skin' => 'inline',
122 'label_block' => false,
123 'condition' => [
124 'tab_icon[value]!' => '',
125 ],
126 ]
127 );
128
129 $repeater->add_control(
130 'element_id',
131 [
132 'label' => esc_html__( 'CSS ID', 'elementor' ),
133 'type' => Controls_Manager::TEXT,
134 'default' => '',
135 'ai' => [
136 'active' => false,
137 ],
138 'dynamic' => [
139 'active' => true,
140 ],
141 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
142 'style_transfer' => false,
143 'classes' => 'elementor-control-direction-ltr',
144 ]
145 );
146
147 $this->add_control( 'tabs', [
148 'label' => esc_html__( 'Tabs Items', 'elementor' ),
149 'type' => Control_Nested_Repeater::CONTROL_TYPE,
150 'fields' => $repeater->get_controls(),
151 'default' => [
152 [
153 'tab_title' => esc_html__( 'Tab #1', 'elementor' ),
154 ],
155 [
156 'tab_title' => esc_html__( 'Tab #2', 'elementor' ),
157 ],
158 [
159 'tab_title' => esc_html__( 'Tab #3', 'elementor' ),
160 ],
161 ],
162 'title_field' => '{{{ tab_title }}}',
163 'button_text' => 'Add Tab',
164 ] );
165
166 $styling_block_start = '--n-tabs-direction: column; --n-tabs-heading-direction: row; --n-tabs-heading-width: initial; --n-tabs-title-flex-basis: content; --n-tabs-title-flex-shrink: 0;';
167 $styling_block_end = '--n-tabs-direction: column-reverse; --n-tabs-heading-direction: row; --n-tabs-heading-width: initial; --n-tabs-title-flex-basis: content; --n-tabs-title-flex-shrink: 0';
168 $styling_inline_end = '--n-tabs-direction: row-reverse; --n-tabs-heading-direction: column; --n-tabs-heading-width: 240px; --n-tabs-title-flex-basis: initial; --n-tabs-title-flex-shrink: initial;';
169 $styling_inline_start = '--n-tabs-direction: row; --n-tabs-heading-direction: column; --n-tabs-heading-width: 240px; --n-tabs-title-flex-basis: initial; --n-tabs-title-flex-shrink: initial;';
170
171 $this->add_responsive_control( 'tabs_direction', [
172 'label' => esc_html__( 'Direction', 'elementor' ),
173 'type' => Controls_Manager::CHOOSE,
174 'options' => [
175 'block-start' => [
176 'title' => esc_html__( 'Above', 'elementor' ),
177 'icon' => 'eicon-v-align-top',
178 ],
179 'block-end' => [
180 'title' => esc_html__( 'Below', 'elementor' ),
181 'icon' => 'eicon-v-align-bottom',
182 ],
183 'inline-end' => [
184 'title' => esc_html__( 'After', 'elementor' ),
185 'icon' => 'eicon-h-align-' . $end,
186 ],
187 'inline-start' => [
188 'title' => esc_html__( 'Before', 'elementor' ),
189 'icon' => 'eicon-h-align-' . $start,
190 ],
191 ],
192 'separator' => 'before',
193 'selectors_dictionary' => [
194 'block-start' => $styling_block_start,
195 'block-end' => $styling_block_end,
196 'inline-end' => $styling_inline_end,
197 'inline-start' => $styling_inline_start,
198 // Styling duplication for BC reasons.
199 'top' => $styling_block_start,
200 'bottom' => $styling_block_end,
201 'end' => $styling_inline_end,
202 'start' => $styling_inline_start,
203 ],
204 'selectors' => [
205 '{{WRAPPER}}' => '{{VALUE}}',
206 ],
207 'control_type' => 'content',
208 ] );
209
210 $this->add_responsive_control( 'tabs_justify_horizontal', [
211 'label' => esc_html__( 'Justify', 'elementor' ),
212 'type' => Controls_Manager::CHOOSE,
213 'options' => [
214 'start' => [
215 'title' => esc_html__( 'Start', 'elementor' ),
216 'icon' => "eicon-align-$start_logical-h",
217 ],
218 'center' => [
219 'title' => esc_html__( 'Center', 'elementor' ),
220 'icon' => 'eicon-align-center-h',
221 ],
222 'end' => [
223 'title' => esc_html__( 'End', 'elementor' ),
224 'icon' => "eicon-align-$end_logical-h",
225 ],
226 'stretch' => [
227 'title' => esc_html__( 'Stretch', 'elementor' ),
228 'icon' => 'eicon-align-stretch-h',
229 ],
230 ],
231 'selectors_dictionary' => [
232 'start' => '--n-tabs-heading-justify-content: flex-start; --n-tabs-title-width: initial; --n-tabs-title-height: initial; --n-tabs-title-align-items: center; --n-tabs-title-flex-grow: 0;',
233 'center' => '--n-tabs-heading-justify-content: center; --n-tabs-title-width: initial; --n-tabs-title-height: initial; --n-tabs-title-align-items: center; --n-tabs-title-flex-grow: 0;',
234 'end' => '--n-tabs-heading-justify-content: flex-end; --n-tabs-title-width: initial; --n-tabs-title-height: initial; --n-tabs-title-align-items: center; --n-tabs-title-flex-grow: 0;',
235 'stretch' => '--n-tabs-heading-justify-content: initial; --n-tabs-title-width: 100%; --n-tabs-title-height: initial; --n-tabs-title-align-items: center; --n-tabs-title-flex-grow: 1;',
236 ],
237 'selectors' => [
238 '{{WRAPPER}}' => '{{VALUE}}',
239 ],
240 'condition' => [
241 'tabs_direction' => [
242 '',
243 'block-start',
244 'block-end',
245 'top',
246 'bottom',
247 ],
248 ],
249 'frontend_available' => true,
250 ] );
251
252 $this->add_responsive_control( 'tabs_justify_vertical', [
253 'label' => esc_html__( 'Justify', 'elementor' ),
254 'type' => Controls_Manager::CHOOSE,
255 'options' => [
256 'start' => [
257 'title' => esc_html__( 'Start', 'elementor' ),
258 'icon' => 'eicon-align-start-v',
259 ],
260 'center' => [
261 'title' => esc_html__( 'Center', 'elementor' ),
262 'icon' => 'eicon-align-center-v',
263 ],
264 'end' => [
265 'title' => esc_html__( 'End', 'elementor' ),
266 'icon' => 'eicon-align-end-v',
267 ],
268 'stretch' => [
269 'title' => esc_html__( 'Stretch', 'elementor' ),
270 'icon' => 'eicon-align-stretch-v',
271 ],
272 ],
273 'selectors_dictionary' => [
274 'start' => '--n-tabs-heading-justify-content: flex-start; --n-tabs-title-width: initial; --n-tabs-title-height: initial; --n-tabs-title-align-items: initial; --n-tabs-heading-wrap: wrap; --n-tabs-title-flex-basis: content',
275 'center' => '--n-tabs-heading-justify-content: center; --n-tabs-title-width: initial; --n-tabs-title-height: initial; --n-tabs-title-align-items: initial; --n-tabs-heading-wrap: wrap; --n-tabs-title-flex-basis: content',
276 'end' => '--n-tabs-heading-justify-content: flex-end; --n-tabs-title-width: initial; --n-tabs-title-height: initial; --n-tabs-title-align-items: initial; --n-tabs-heading-wrap: wrap; --n-tabs-title-flex-basis: content',
277 'stretch' => '--n-tabs-heading-justify-content: flex-start; --n-tabs-title-width: initial; --n-tabs-title-height: 100%; --n-tabs-title-align-items: center; --n-tabs-heading-wrap: nowrap; --n-tabs-title-flex-basis: auto',
278 ],
279 'selectors' => [
280 '{{WRAPPER}}' => '{{VALUE}}',
281 ],
282 'condition' => [
283 'tabs_direction' => [
284 'inline-start',
285 'inline-end',
286 'start',
287 'end',
288 ],
289 ],
290 ] );
291
292 $this->add_responsive_control( 'tabs_width', [
293 'label' => esc_html__( 'Width', 'elementor' ),
294 'type' => Controls_Manager::SLIDER,
295 'range' => [
296 '%' => [
297 'min' => 10,
298 'max' => 50,
299 ],
300 'px' => [
301 'min' => 20,
302 'max' => 600,
303 ],
304 ],
305 'default' => [
306 'unit' => '%',
307 ],
308 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
309 'selectors' => [
310 '{{WRAPPER}}' => '--n-tabs-heading-width: {{SIZE}}{{UNIT}}',
311 ],
312 'condition' => [
313 'tabs_direction' => [
314 'inline-start',
315 'inline-end',
316 'start',
317 'end',
318 ],
319 ],
320 ] );
321
322 $this->add_responsive_control( 'title_alignment', [
323 'label' => esc_html__( 'Align Title', 'elementor' ),
324 'type' => Controls_Manager::CHOOSE,
325 'options' => [
326 'start' => [
327 'title' => esc_html__( 'Start', 'elementor' ),
328 'icon' => 'eicon-text-align-left',
329 ],
330 'center' => [
331 'title' => esc_html__( 'Center', 'elementor' ),
332 'icon' => 'eicon-text-align-center',
333 ],
334 'end' => [
335 'title' => esc_html__( 'End', 'elementor' ),
336 'icon' => 'eicon-text-align-right',
337 ],
338 ],
339 'selectors_dictionary' => [
340 'start' => '--n-tabs-title-justify-content: flex-start; --n-tabs-title-align-items: flex-start; --n-tabs-title-text-align: start;',
341 'center' => '--n-tabs-title-justify-content: center; --n-tabs-title-align-items: center; --n-tabs-title-text-align: center;',
342 'end' => '--n-tabs-title-justify-content: flex-end; --n-tabs-title-align-items: flex-end; --n-tabs-title-text-align: end;',
343 ],
344 'selectors' => [
345 '{{WRAPPER}}' => '{{VALUE}}',
346 ],
347 ] );
348
349 $this->end_controls_section();
350
351 $this->start_controls_section( 'section_tabs_responsive', [
352 'label' => esc_html__( 'Additional Settings', 'elementor' ),
353 ] );
354
355 $this->add_responsive_control(
356 'horizontal_scroll',
357 [
358 'label' => esc_html__( 'Horizontal Scroll', 'elementor' ),
359 'type' => Controls_Manager::SELECT,
360 'description' => esc_html__( 'Note: Scroll tabs if they don’t fit into their parent container.', 'elementor' ),
361 'options' => [
362 'disable' => esc_html__( 'Disable', 'elementor' ),
363 'enable' => esc_html__( 'Enable', 'elementor' ),
364 ],
365 'default' => 'disable',
366 'selectors_dictionary' => [
367 'disable' => '--n-tabs-heading-wrap: wrap; --n-tabs-heading-overflow-x: initial; --n-tabs-title-white-space: initial;',
368 'enable' => '--n-tabs-heading-wrap: nowrap; --n-tabs-heading-overflow-x: scroll; --n-tabs-title-white-space: nowrap;',
369 ],
370 'selectors' => [
371 '{{WRAPPER}}' => '{{VALUE}}',
372 ],
373 'frontend_available' => true,
374 'condition' => [
375 'tabs_direction' => [
376 '',
377 'block-start',
378 'block-end',
379 'top',
380 'bottom',
381 ],
382 ],
383 ]
384 );
385
386 $dropdown_options = [
387 'none' => esc_html__( 'None', 'elementor' ),
388 ];
389 $excluded_breakpoints = [
390 'laptop',
391 'tablet_extra',
392 'widescreen',
393 ];
394
395 foreach ( Plugin::$instance->breakpoints->get_active_breakpoints() as $breakpoint_key => $breakpoint_instance ) {
396 // Exclude the larger breakpoints from the dropdown selector.
397 if ( in_array( $breakpoint_key, $excluded_breakpoints, true ) ) {
398 continue;
399 }
400
401 $dropdown_options[ $breakpoint_key ] = sprintf(
402 /* translators: 1: Breakpoint label, 2: `>` character, 3: Breakpoint value. */
403 esc_html__( '%1$s (%2$s %3$dpx)', 'elementor' ),
404 $breakpoint_instance->get_label(),
405 '>',
406 $breakpoint_instance->get_value()
407 );
408 }
409
410 $this->add_control(
411 'breakpoint_selector',
412 [
413 'label' => esc_html__( 'Breakpoint', 'elementor' ),
414 'type' => Controls_Manager::SELECT,
415 'description' => esc_html__( 'Note: Choose at which breakpoint tabs will automatically switch to a vertical (“accordion”) layout.', 'elementor' ),
416 'options' => $dropdown_options,
417 'default' => 'mobile',
418 'prefix_class' => 'e-n-tabs-',
419 ]
420 );
421
422 $this->end_controls_section();
423
424 $this->start_controls_section( 'section_tabs_style', [
425 'label' => esc_html__( 'Tabs', 'elementor' ),
426 'tab' => Controls_Manager::TAB_STYLE,
427 ] );
428
429 $this->add_responsive_control( 'tabs_title_space_between', [
430 'label' => esc_html__( 'Gap between tabs', 'elementor' ),
431 'type' => Controls_Manager::SLIDER,
432 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
433 'range' => [
434 'px' => [
435 'max' => 400,
436 ],
437 'em' => [
438 'max' => 40,
439 ],
440 'rem' => [
441 'max' => 40,
442 ],
443 ],
444 'selectors' => [
445 '{{WRAPPER}}' => '--n-tabs-title-gap: {{SIZE}}{{UNIT}}',
446 ],
447 ] );
448
449 $this->add_responsive_control( 'tabs_title_spacing', [
450 'label' => esc_html__( 'Distance from content', 'elementor' ),
451 'type' => Controls_Manager::SLIDER,
452 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
453 'range' => [
454 'px' => [
455 'max' => 400,
456 ],
457 'em' => [
458 'max' => 40,
459 ],
460 'rem' => [
461 'max' => 40,
462 ],
463 ],
464 'selectors' => [
465 '{{WRAPPER}}' => '--n-tabs-gap: {{SIZE}}{{UNIT}}',
466 ],
467 ] );
468
469 $this->start_controls_tabs( 'tabs_title_style' );
470
471 $this->start_controls_tab(
472 'tabs_title_normal',
473 [
474 'label' => esc_html__( 'Normal', 'elementor' ),
475 ]
476 );
477
478 $this->add_group_control(
479 Group_Control_Background::get_type(),
480 [
481 'name' => 'tabs_title_background_color',
482 'types' => [ 'classic', 'gradient' ],
483 'exclude' => [ 'image' ],
484 'selector' => '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="false"]:not( :hover )',
485 'fields_options' => [
486 'color' => [
487 'label' => esc_html__( 'Background Color', 'elementor' ),
488 'selectors' => [
489 '{{SELECTOR}}' => 'background: {{VALUE}}',
490 ],
491 ],
492 ],
493 ]
494 );
495
496 $this->add_group_control(
497 Group_Control_Border::get_type(),
498 [
499 'name' => 'tabs_title_border',
500 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
501 'fields_options' => [
502 'color' => [
503 'label' => esc_html__( 'Border Color', 'elementor' ),
504 ],
505 'width' => [
506 'label' => esc_html__( 'Border Width', 'elementor' ),
507 ],
508 ],
509 ]
510 );
511
512 $this->add_group_control(
513 Group_Control_Box_Shadow::get_type(),
514 [
515 'name' => 'tabs_title_box_shadow',
516 'label' => esc_html__( 'Shadow', 'elementor' ),
517 'separator' => 'after',
518 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
519 ]
520 );
521
522 $this->end_controls_tab();
523
524 $this->start_controls_tab(
525 'tabs_title_hover',
526 [
527 'label' => esc_html__( 'Hover', 'elementor' ),
528 ]
529 );
530
531 $this->add_group_control(
532 Group_Control_Background::get_type(),
533 [
534 'name' => 'tabs_title_background_color_hover',
535 'types' => [ 'classic', 'gradient' ],
536 'exclude' => [ 'image' ],
537 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
538 'fields_options' => [
539 'background' => [
540 'default' => 'classic',
541 ],
542 'color' => [
543 'global' => [
544 'default' => Global_Colors::COLOR_ACCENT,
545 ],
546 'label' => esc_html__( 'Background Color', 'elementor' ),
547 'selectors' => [
548 '{{SELECTOR}}' => 'background: {{VALUE}};',
549 ],
550 ],
551 ],
552 ]
553 );
554
555 $this->add_group_control(
556 Group_Control_Border::get_type(),
557 [
558 'name' => 'tabs_title_border_hover',
559 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
560 'fields_options' => [
561 'color' => [
562 'label' => esc_html__( 'Border Color', 'elementor' ),
563 ],
564 'width' => [
565 'label' => esc_html__( 'Border Width', 'elementor' ),
566 ],
567 ],
568 ]
569 );
570
571 $this->add_group_control(
572 Group_Control_Box_Shadow::get_type(),
573 [
574 'name' => 'tabs_title_box_shadow_hover',
575 'label' => esc_html__( 'Shadow', 'elementor' ),
576 'separator' => 'after',
577 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
578 ]
579 );
580
581 $this->add_control(
582 'hover_animation',
583 [
584 'label' => esc_html__( 'Hover Animation', 'elementor' ),
585 'type' => Controls_Manager::HOVER_ANIMATION,
586 ]
587 );
588
589 $this->add_control(
590 'tabs_title_transition_duration',
591 [
592 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
593 'type' => Controls_Manager::SLIDER,
594 'selectors' => [
595 '{{WRAPPER}}' => '--n-tabs-title-transition: {{SIZE}}s',
596 ],
597 'range' => [
598 'px' => [
599 'min' => 0,
600 'max' => 3,
601 'step' => 0.1,
602 ],
603 ],
604 ]
605 );
606
607 $this->end_controls_tab();
608
609 $this->start_controls_tab(
610 'tabs_title_active',
611 [
612 'label' => esc_html__( 'Active', 'elementor' ),
613 ]
614 );
615
616 $this->add_group_control(
617 Group_Control_Background::get_type(),
618 [
619 'name' => 'tabs_title_background_color_active',
620 'types' => [ 'classic', 'gradient' ],
621 'exclude' => [ 'image' ],
622 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
623 'fields_options' => [
624 'background' => [
625 'default' => 'classic',
626 ],
627 'color' => [
628 'global' => [
629 'default' => Global_Colors::COLOR_ACCENT,
630 ],
631 'label' => esc_html__( 'Background Color', 'elementor' ),
632 'selectors' => [
633 '{{SELECTOR}}' => 'background: {{VALUE}};',
634 ],
635 ],
636 ],
637 ]
638 );
639
640 $this->add_group_control(
641 Group_Control_Border::get_type(),
642 [
643 'name' => 'tabs_title_border_active',
644 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
645 'fields_options' => [
646 'color' => [
647 'label' => esc_html__( 'Border Color', 'elementor' ),
648 ],
649 'width' => [
650 'label' => esc_html__( 'Border Width', 'elementor' ),
651 ],
652 ],
653 ]
654 );
655
656 $this->add_group_control(
657 Group_Control_Box_Shadow::get_type(),
658 [
659 'name' => 'tabs_title_box_shadow_active',
660 'label' => esc_html__( 'Shadow', 'elementor' ),
661 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
662 ]
663 );
664
665 $this->end_controls_tab();
666
667 $this->end_controls_tabs();
668
669 $this->add_responsive_control(
670 'tabs_title_border_radius',
671 [
672 'label' => esc_html__( 'Border Radius', 'elementor' ),
673 'type' => Controls_Manager::DIMENSIONS,
674 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
675 'separator' => 'before',
676 'selectors' => [
677 '{{WRAPPER}}' => '--n-tabs-title-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
678 ],
679 ]
680 );
681
682 $this->add_responsive_control(
683 'padding',
684 [
685 'label' => esc_html__( 'Padding', 'elementor' ),
686 'type' => Controls_Manager::DIMENSIONS,
687 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
688 'selectors' => [
689 '{{WRAPPER}}' => '--n-tabs-title-padding-top: {{TOP}}{{UNIT}}; --n-tabs-title-padding-right: {{RIGHT}}{{UNIT}}; --n-tabs-title-padding-bottom: {{BOTTOM}}{{UNIT}}; --n-tabs-title-padding-left: {{LEFT}}{{UNIT}};',
690 ],
691 ]
692 );
693
694 $this->end_controls_section();
695
696 $this->start_controls_section( 'section_title_style', [
697 'label' => esc_html__( 'Titles', 'elementor' ),
698 'tab' => Controls_Manager::TAB_STYLE,
699 ] );
700
701 $this->add_group_control( Group_Control_Typography::get_type(), [
702 'name' => 'title_typography',
703 'global' => [
704 'default' => Global_Typography::TYPOGRAPHY_ACCENT,
705 ],
706 'selector' => "{$heading_selector} > :is( .e-n-tab-title > .e-n-tab-title-text, .e-n-tab-title )",
707 'fields_options' => [
708 'font_size' => [
709 'selectors' => [
710 '{{WRAPPER}}' => '--n-tabs-title-font-size: {{SIZE}}{{UNIT}}',
711 ],
712 ],
713 ],
714 ] );
715
716 $this->start_controls_tabs( 'title_style' );
717
718 $this->start_controls_tab(
719 'title_normal',
720 [
721 'label' => esc_html__( 'Normal', 'elementor' ),
722 ]
723 );
724
725 $this->add_control(
726 'title_text_color',
727 [
728 'label' => esc_html__( 'Color', 'elementor' ),
729 'type' => Controls_Manager::COLOR,
730 'selectors' => [
731 '{{WRAPPER}}' => '--n-tabs-title-color: {{VALUE}}',
732 ],
733 ]
734 );
735
736 $this->add_group_control(
737 Group_Control_Text_Shadow::get_type(),
738 [
739 'name' => 'title_text_shadow',
740 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
741 'fields_options' => [
742 'text_shadow_type' => [
743 'label' => esc_html__( 'Shadow', 'elementor' ),
744 ],
745 ],
746 ]
747 );
748
749 $this->add_group_control(
750 Group_Control_Text_Stroke::get_type(),
751 [
752 'name' => 'title_text_stroke',
753 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover ) :is( span, a, i )",
754 'fields_options' => [
755 'text_stroke_type' => [
756 'label' => esc_html__( 'Stroke', 'elementor' ),
757 ],
758 ],
759 ]
760 );
761
762 $this->end_controls_tab();
763
764 $this->start_controls_tab(
765 'title_hover',
766 [
767 'label' => esc_html__( 'Hover', 'elementor' ),
768 ]
769 );
770
771 $this->add_control(
772 'title_text_color_hover',
773 [
774 'label' => esc_html__( 'Color', 'elementor' ),
775 'type' => Controls_Manager::COLOR,
776 'selectors' => [
777 '{{WRAPPER}} [data-touch-mode="false"] .e-n-tab-title[aria-selected="false"]:hover' => '--n-tabs-title-color-hover: {{VALUE}}',
778 ],
779 ]
780 );
781
782 $this->add_group_control(
783 Group_Control_Text_Shadow::get_type(),
784 [
785 'name' => 'title_text_shadow_hover',
786 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
787 'fields_options' => [
788 'text_shadow_type' => [
789 'label' => esc_html__( 'Shadow', 'elementor' ),
790 ],
791 ],
792
793 ]
794 );
795
796 $this->add_group_control(
797 Group_Control_Text_Stroke::get_type(),
798 [
799 'name' => 'title_text_stroke_hover',
800 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover :is( span, a, i )",
801 'fields_options' => [
802 'text_stroke_type' => [
803 'label' => esc_html__( 'Stroke', 'elementor' ),
804 ],
805 ],
806 ]
807 );
808
809 $this->end_controls_tab();
810
811 $this->start_controls_tab(
812 'title_active',
813 [
814 'label' => esc_html__( 'Active', 'elementor' ),
815 ]
816 );
817
818 $this->add_control(
819 'title_text_color_active',
820 [
821 'label' => esc_html__( 'Color', 'elementor' ),
822 'type' => Controls_Manager::COLOR,
823 'selectors' => [
824 '{{WRAPPER}}' => '--n-tabs-title-color-active: {{VALUE}}',
825 ],
826 ]
827 );
828
829 $this->add_group_control(
830 Group_Control_Text_Shadow::get_type(),
831 [
832 'name' => 'title_text_shadow_active',
833 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
834 'fields_options' => [
835 'text_shadow_type' => [
836 'label' => esc_html__( 'Shadow', 'elementor' ),
837 ],
838 ],
839 ]
840 );
841
842 $this->add_group_control(
843 Group_Control_Text_Stroke::get_type(),
844 [
845 'name' => 'title_text_stroke_active',
846 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"] :is( span, a, i ), {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover :is( span, a, i )",
847 'fields_options' => [
848 'text_stroke_type' => [
849 'label' => esc_html__( 'Stroke', 'elementor' ),
850 ],
851 ],
852 ]
853 );
854
855 $this->end_controls_tab();
856
857 $this->end_controls_tabs();
858
859 $this->end_controls_section();
860
861 $this->start_controls_section( 'icon_section_style', [
862 'label' => esc_html__( 'Icon', 'elementor' ),
863 'tab' => Controls_Manager::TAB_STYLE,
864 ] );
865
866 $styling_block_start = '--n-tabs-title-direction: column; --n-tabs-icon-order: initial; --n-tabs-title-justify-content-toggle: center; --n-tabs-title-align-items-toggle: initial;';
867 $styling_block_end = '--n-tabs-title-direction: column; --n-tabs-icon-order: 1; --n-tabs-title-justify-content-toggle: center; --n-tabs-title-align-items-toggle: initial;';
868 $styling_inline_start = '--n-tabs-title-direction: row; --n-tabs-icon-order: initial; --n-tabs-title-justify-content-toggle: initial; --n-tabs-title-align-items-toggle: center;';
869 $styling_inline_end = '--n-tabs-title-direction: row; --n-tabs-icon-order: 1; --n-tabs-title-justify-content-toggle: initial; --n-tabs-title-align-items-toggle: center;';
870
871 $this->add_responsive_control( 'icon_position', [
872 'label' => esc_html__( 'Position', 'elementor' ),
873 'type' => Controls_Manager::CHOOSE,
874 'options' => [
875 'block-start' => [
876 'title' => esc_html__( 'Above', 'elementor' ),
877 'icon' => 'eicon-v-align-top',
878 ],
879 'inline-end' => [
880 'title' => esc_html__( 'After', 'elementor' ),
881 'icon' => 'eicon-h-align-' . $end,
882 ],
883 'block-end' => [
884 'title' => esc_html__( 'Below', 'elementor' ),
885 'icon' => 'eicon-v-align-bottom',
886 ],
887 'inline-start' => [
888 'title' => esc_html__( 'Before', 'elementor' ),
889 'icon' => 'eicon-h-align-' . $start,
890 ],
891 ],
892 'selectors_dictionary' => [
893 // The toggle variables for 'align items' and 'justify content' have been added to separate the styling of the two 'flex direction' modes.
894 'block-start' => $styling_block_start,
895 'inline-end' => $styling_inline_end,
896 'block-end' => $styling_block_end,
897 'inline-start' => $styling_inline_start,
898 // Styling duplication for BC reasons.
899 'top' => $styling_block_start,
900 'bottom' => $styling_block_end,
901 'start' => $styling_inline_start,
902 'end' => $styling_inline_end,
903 ],
904 'selectors' => [
905 '{{WRAPPER}}' => '{{VALUE}}',
906 ],
907 ] );
908
909 $this->add_responsive_control( 'icon_size', [
910 'label' => esc_html__( 'Size', 'elementor' ),
911 'type' => Controls_Manager::SLIDER,
912 'range' => [
913 'px' => [
914 'max' => 100,
915 ],
916 'em' => [
917 'max' => 10,
918 ],
919 'rem' => [
920 'max' => 10,
921 ],
922 ],
923 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ],
924 'selectors' => [
925 '{{WRAPPER}}' => '--n-tabs-icon-size: {{SIZE}}{{UNIT}}',
926 ],
927 ] );
928
929 $this->add_responsive_control( 'icon_spacing', [
930 'label' => esc_html__( 'Spacing', 'elementor' ),
931 'type' => Controls_Manager::SLIDER,
932 'range' => [
933 'px' => [
934 'max' => 400,
935 ],
936 'vw' => [
937 'max' => 50,
938 'step' => 0.1,
939 ],
940 ],
941 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ],
942 'selectors' => [
943 '{{WRAPPER}}' => '--n-tabs-icon-gap: {{SIZE}}{{UNIT}}',
944 ],
945 ] );
946
947 $this->start_controls_tabs( 'icon_style_states' );
948
949 $this->start_controls_tab(
950 'icon_section_normal',
951 [
952 'label' => esc_html__( 'Normal', 'elementor' ),
953 ]
954 );
955
956 $this->add_control( 'icon_color', [
957 'label' => esc_html__( 'Color', 'elementor' ),
958 'type' => Controls_Manager::COLOR,
959 'selectors' => [
960 '{{WRAPPER}}' => '--n-tabs-icon-color: {{VALUE}};',
961 ],
962 ] );
963
964 $this->end_controls_tab();
965
966 $this->start_controls_tab(
967 'icon_section_hover',
968 [
969 'label' => esc_html__( 'Hover', 'elementor' ),
970 ]
971 );
972
973 $this->add_control( 'icon_color_hover', [
974 'label' => esc_html__( 'Color', 'elementor' ),
975 'type' => Controls_Manager::COLOR,
976 'selectors' => [
977 '{{WRAPPER}} [data-touch-mode="false"] .e-n-tab-title[aria-selected="false"]:hover' => '--n-tabs-icon-color-hover: {{VALUE}};',
978 ],
979 ] );
980
981 $this->end_controls_tab();
982
983 $this->start_controls_tab(
984 'icon_section_active',
985 [
986 'label' => esc_html__( 'Active', 'elementor' ),
987 ]
988 );
989
990 $this->add_control( 'icon_color_active', [
991 'label' => esc_html__( 'Color', 'elementor' ),
992 'type' => Controls_Manager::COLOR,
993 'selectors' => [
994 '{{WRAPPER}}' => '--n-tabs-icon-color-active: {{VALUE}};',
995 ],
996 ] );
997
998 $this->end_controls_tab();
999
1000 $this->end_controls_tabs();
1001
1002 $this->end_controls_section();
1003
1004 $this->start_controls_section( 'section_box_style', [
1005 'label' => esc_html__( 'Content', 'elementor' ),
1006 'tab' => Controls_Manager::TAB_STYLE,
1007 ] );
1008
1009 $this->add_group_control(
1010 Group_Control_Background::get_type(),
1011 [
1012 'name' => 'box_background_color',
1013 'types' => [ 'classic', 'gradient' ],
1014 'exclude' => [ 'image' ],
1015 'selector' => $content_selector,
1016 'fields_options' => [
1017 'color' => [
1018 'label' => esc_html__( 'Background Color', 'elementor' ),
1019 ],
1020 ],
1021 ]
1022 );
1023
1024 $this->add_group_control(
1025 Group_Control_Border::get_type(),
1026 [
1027 'name' => 'box_border',
1028 'selector' => $content_selector,
1029 'fields_options' => [
1030 'color' => [
1031 'label' => esc_html__( 'Border Color', 'elementor' ),
1032 ],
1033 'width' => [
1034 'label' => esc_html__( 'Border Width', 'elementor' ),
1035 ],
1036 ],
1037 ]
1038 );
1039
1040 $this->add_responsive_control(
1041 'box_border_radius',
1042 [
1043 'label' => esc_html__( 'Border Radius', 'elementor' ),
1044 'type' => Controls_Manager::DIMENSIONS,
1045 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
1046 'selectors' => [
1047 $content_selector => '--border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1048 ],
1049 ]
1050 );
1051
1052 $this->add_group_control(
1053 Group_Control_Box_Shadow::get_type(),
1054 [
1055 'name' => 'box_shadow_box_shadow',
1056 'selector' => $content_selector,
1057 'condition' => [
1058 'box_height!' => 'height',
1059 ],
1060 ]
1061 );
1062
1063 $this->add_responsive_control(
1064 'box_padding',
1065 [
1066 'label' => esc_html__( 'Padding', 'elementor' ),
1067 'type' => Controls_Manager::DIMENSIONS,
1068 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
1069 'selectors' => [
1070 $content_selector => '--padding-top: {{TOP}}{{UNIT}}; --padding-right: {{RIGHT}}{{UNIT}}; --padding-bottom: {{BOTTOM}}{{UNIT}}; --padding-left: {{LEFT}}{{UNIT}};',
1071 ],
1072 ]
1073 );
1074
1075 $this->end_controls_section();
1076 }
1077
1078 protected function render_tab_titles_html( $item_settings ): void {
1079 $setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $item_settings['index'] );
1080 $title = $item_settings['item']['tab_title'];
1081 $css_classes = [ 'e-n-tab-title' ];
1082
1083 if ( $item_settings['settings']['hover_animation'] ) {
1084 $css_classes[] = 'elementor-animation-' . $item_settings['settings']['hover_animation'];
1085 }
1086
1087 $this->add_render_attribute( $setting_key, [
1088 'id' => $item_settings['tab_id'],
1089 'class' => $css_classes,
1090 'aria-selected' => 1 === $item_settings['tab_count'] ? 'true' : 'false',
1091 'data-tab-index' => $item_settings['tab_count'],
1092 'role' => 'tab',
1093 'tabindex' => 1 === $item_settings['tab_count'] ? '0' : '-1',
1094 'aria-controls' => $item_settings['container_id'],
1095 'style' => '--n-tabs-title-order: ' . $item_settings['tab_count'] . ';',
1096 ] );
1097 ?>
1098 <button <?php $this->print_render_attribute_string( $setting_key ); ?>>
1099 <?php $this->maybe_render_tab_icons_html( $item_settings ); ?>
1100 <span <?php $this->print_render_attribute_string( 'tab-title-text' ); ?>>
1101 <?php echo wp_kses_post( $title ); ?>
1102 </span>
1103 </button>
1104 <?php
1105 }
1106
1107 protected function maybe_render_tab_icons_html( $item_settings ): void {
1108 $icon_settings = $item_settings['item']['tab_icon'];
1109
1110 if ( empty( $icon_settings['value'] ) ) {
1111 return;
1112 }
1113
1114 $active_icon_settings = $this->is_active_icon_exist( $item_settings['item'] )
1115 ? $item_settings['item']['tab_icon_active']
1116 : $icon_settings;
1117 ?>
1118 <span <?php $this->print_render_attribute_string( 'tab-icon' ); ?>>
1119 <?php Icons_Manager::render_icon( $icon_settings, [ 'aria-hidden' => 'true' ] ); ?>
1120 <?php Icons_Manager::render_icon( $active_icon_settings, [ 'aria-hidden' => 'true' ] ); ?>
1121 </span>
1122 <?php
1123 }
1124
1125 protected function render_tab_containers_html( $settings ): void {
1126 foreach ( $settings['tabs'] as $index => $item ) {
1127 $item_settings = $this->tab_item_settings[ $index ];
1128 $this->print_child( $item_settings['index'], $item_settings );
1129 }
1130 }
1131
1132
1133 /**
1134 * Print the content area.
1135 *
1136 * @param int $index
1137 * @param array $item_settings
1138 */
1139 public function print_child( $index, $item_settings = [] ) {
1140 $children = $this->get_children();
1141 $child_ids = [];
1142
1143 foreach ( $children as $child ) {
1144 $child_ids[] = $child->get_id();
1145 }
1146
1147 // Add data-tab-index attribute to the content area.
1148 $add_attribute_to_container = function ( $should_render, $container ) use ( $item_settings, $child_ids ) {
1149 if ( in_array( $container->get_id(), $child_ids ) ) {
1150 $this->add_attributes_to_container( $container, $item_settings );
1151 }
1152
1153 return $should_render;
1154 };
1155
1156 add_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container, 10, 3 );
1157 if ( isset( $children[ $index ] ) ) {
1158 $children[ $index ]->print_element();
1159 }
1160 remove_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container );
1161 }
1162
1163 protected function add_attributes_to_container( $container, $item_settings ) {
1164 $container->add_render_attribute( '_wrapper', [
1165 'id' => $item_settings['container_id'],
1166 'role' => 'tabpanel',
1167 'aria-labelledby' => $item_settings['tab_id'],
1168 'data-tab-index' => $item_settings['tab_count'],
1169 'style' => '--n-tabs-title-order: ' . $item_settings['tab_count'] . ';',
1170 'class' => 0 === $item_settings['index'] ? 'e-active' : '',
1171 ] );
1172 }
1173
1174 protected function render() {
1175 $settings = $this->get_settings_for_display();
1176 $widget_number = $this->get_id_int();
1177
1178 if ( ! empty( $settings['link'] ) ) {
1179 $this->add_link_attributes( 'elementor-tabs', $settings['link'] );
1180 }
1181
1182 $this->add_render_attribute( 'elementor-tabs', [
1183 'class' => 'e-n-tabs',
1184 'data-widget-number' => $widget_number,
1185 'aria-label' => esc_html__( 'Tabs. Open items with Enter or Space, close with Escape and navigate using the Arrow keys.', 'elementor' ),
1186 ] );
1187
1188 $this->add_render_attribute( 'tab-title-text', 'class', 'e-n-tab-title-text' );
1189 $this->add_render_attribute( 'tab-icon', 'class', 'e-n-tab-icon' );
1190 $this->add_render_attribute( 'tab-icon-active', 'class', [ 'e-n-tab-icon' ] );
1191 ?>
1192 <div <?php $this->print_render_attribute_string( 'elementor-tabs' ); ?>>
1193 <div class="e-n-tabs-heading" role="tablist">
1194 <?php
1195 foreach ( $settings['tabs'] as $index => $item ) {
1196 $tab_count = $index + 1;
1197
1198 $tab_id = empty( $item['element_id'] )
1199 ? 'e-n-tab-title-' . $widget_number . $tab_count
1200 : $item['element_id'];
1201
1202 $item_settings = [
1203 'index' => $index,
1204 'tab_count' => $tab_count,
1205 'tab_id' => $tab_id,
1206 'container_id' => 'e-n-tab-content-' . $widget_number . $tab_count,
1207 'widget_number' => $widget_number,
1208 'item' => $item,
1209 'settings' => $settings,
1210 ];
1211
1212 $this->tab_item_settings[] = $item_settings;
1213
1214 $this->render_tab_titles_html( $item_settings );
1215 }
1216 ?>
1217 </div>
1218 <div class="e-n-tabs-content">
1219 <?php $this->render_tab_containers_html( $settings ); ?>
1220 </div>
1221 </div>
1222 <?php
1223 }
1224
1225 protected function get_initial_config(): array {
1226 if ( Plugin::$instance->experiments->is_feature_active( 'e_nested_atomic_repeaters' ) ) {
1227 return array_merge( parent::get_initial_config(), [
1228 'support_improved_repeaters' => true,
1229 'target_container' => [ '.e-n-tabs-heading' ],
1230 'node' => 'button',
1231 ] );
1232 }
1233
1234 return parent::get_initial_config();
1235 }
1236
1237 protected function content_template_single_repeater_item() {
1238 ?>
1239 <#
1240 const tabIndex = view.collection.length,
1241 elementUid = view.getIDInt().toString(),
1242 item = data,
1243 hoverAnimationSetting = view?.container?.settings?.attributes?.hover_animation;
1244 hoverAnimationClass = hoverAnimationSetting
1245 ? `elementor-animation-${ hoverAnimationSetting }`
1246 : '';
1247 #>
1248 <?php $this->content_template_single_item( '{{ tabIndex }}', '{{ item }}', '{{ elementUid }}', '{{ hoverAnimationClass }}' );
1249 }
1250
1251 protected function content_template() {
1252 ?>
1253 <# const elementUid = view.getIDInt().toString(); #>
1254 <div class="e-n-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.', 'elementor' ); ?>">
1255 <# if ( settings['tabs'] ) { #>
1256 <div class="e-n-tabs-heading" role="tablist">
1257 <# _.each( settings['tabs'], function( item, index ) {
1258 const tabIndex = index,
1259 hoverAnimationSetting = settings['hover_animation'],
1260 hoverAnimationClass = hoverAnimationSetting
1261 ? `elementor-animation-${ hoverAnimationSetting }`
1262 : '';
1263 #>
1264 <?php $this->content_template_single_item( '{{ tabIndex }}', '{{ item }}', '{{ elementUid }}', '{{ hoverAnimationClass }}' ); ?>
1265 <# } ); #>
1266 </div>
1267 <div class="e-n-tabs-content"></div>
1268 <# } #>
1269 </div>
1270 <?php
1271 }
1272
1273 private function content_template_single_item( $tab_index, $item, $element_uid, $hover_animation_class ) {
1274 ?>
1275 <#
1276 const tabCount = tabIndex + 1,
1277 tabId = item.element_id
1278 ? item.element_id
1279 : 'e-n-tab-title-' + elementUid + ( tabIndex + 1 ),
1280 tabUid = elementUid + tabCount,
1281 tabIcon = elementor.helpers.renderIcon( view, item.tab_icon, { 'aria-hidden': true }, 'i' , 'object' ),
1282 activeTabIcon = item.tab_icon_active.value
1283 ? elementor.helpers.renderIcon( view, item.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' )
1284 : tabIcon,
1285 escapedHoverAnimationClass = _.escape( hoverAnimationClass );
1286
1287 view.addRenderAttribute( 'tab-title', {
1288 'id': tabId,
1289 'class': [ 'e-n-tab-title',escapedHoverAnimationClass ],
1290 'data-tab-index': tabCount,
1291 'role': 'tab',
1292 'aria-selected': 1 === tabCount ? 'true' : 'false',
1293 'tabindex': 1 === tabCount ? '0' : '-1',
1294 'aria-controls': 'e-n-tab-content-' + tabUid,
1295 'style': '--n-tabs-title-order: ' + tabCount + ';',
1296 }, null, true );
1297
1298 view.addRenderAttribute( 'tab-title-text', {
1299 'class': [ 'e-n-tab-title-text' ],
1300 'data-binding-type': 'repeater-item',
1301 'data-binding-repeater-name': 'tabs',
1302 'data-binding-setting': [ 'tab_title' ],
1303 'data-binding-index': tabCount,
1304 'data-binding-dynamic': 'true',
1305 }, null, true );
1306
1307 view.addRenderAttribute( 'tab-icon', {
1308 'class': [ 'e-n-tab-icon' ],
1309 'data-binding-type': 'repeater-item',
1310 'data-binding-repeater-name': 'tabs',
1311 'data-binding-setting': [ 'tab_icon', 'tab_icon_active' ],
1312 'data-binding-index': tabCount,
1313 }, null, true );
1314 #>
1315
1316 <button {{{ view.getRenderAttributeString( 'tab-title' ) }}}>
1317 <# if ( !! item.tab_icon.value ) { #>
1318 <span {{{ view.getRenderAttributeString( 'tab-icon' ) }}}>{{{ tabIcon.value }}}{{{ activeTabIcon.value }}}</span>
1319 <# } #>
1320
1321 <span {{{ view.getRenderAttributeString( 'tab-title-text' ) }}}>{{{ item.tab_title }}}</span>
1322 </button>
1323 <?php
1324 }
1325
1326 /**
1327 * @param $item
1328 * @return bool
1329 */
1330 private function is_active_icon_exist( $item ) {
1331 return array_key_exists( 'tab_icon_active', $item ) && ! empty( $item['tab_icon_active'] ) && ! empty( $item['tab_icon_active']['value'] );
1332 }
1333 }
1334