PluginProbe
Elementor Website Builder – more than just a page builder / 3.27.5
Elementor Website Builder – more than just a page builder v3.27.5
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.27.5, at modules/nested-tabs/widgets/nested-tabs.php

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