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

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