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

1,294 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 'range' => [
435 'px' => [
436 'min' => 0,
437 'max' => 400,
438 ],
439 ],
440 'size_units' => [ 'px' ],
441 'selectors' => [
442 '{{WRAPPER}}' => '--n-tabs-title-gap: {{SIZE}}{{UNIT}}',
443 ],
444 ] );
445
446 $this->add_responsive_control( 'tabs_title_spacing', [
447 'label' => esc_html__( 'Distance from content', 'elementor' ),
448 'type' => Controls_Manager::SLIDER,
449 'range' => [
450 'px' => [
451 'min' => 0,
452 'max' => 400,
453 ],
454 ],
455 'size_units' => [ 'px' ],
456 'selectors' => [
457 '{{WRAPPER}}' => '--n-tabs-gap: {{SIZE}}{{UNIT}}',
458 ],
459 ] );
460
461 $this->start_controls_tabs( 'tabs_title_style' );
462
463 $this->start_controls_tab(
464 'tabs_title_normal',
465 [
466 'label' => esc_html__( 'Normal', 'elementor' ),
467 ]
468 );
469
470 $this->add_group_control(
471 Group_Control_Background::get_type(),
472 [
473 'name' => 'tabs_title_background_color',
474 'types' => [ 'classic', 'gradient' ],
475 'exclude' => [ 'image' ],
476 'selector' => '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="false"]:not( :hover )',
477 'fields_options' => [
478 'color' => [
479 'label' => esc_html__( 'Background Color', 'elementor' ),
480 'selectors' => [
481 '{{SELECTOR}}' => 'background: {{VALUE}}',
482 ],
483 ],
484 ],
485 ]
486 );
487
488 $this->add_group_control(
489 Group_Control_Border::get_type(),
490 [
491 'name' => 'tabs_title_border',
492 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
493 'fields_options' => [
494 'color' => [
495 'label' => esc_html__( 'Border Color', 'elementor' ),
496 ],
497 'width' => [
498 'label' => esc_html__( 'Border Width', 'elementor' ),
499 ],
500 ],
501 ]
502 );
503
504 $this->add_group_control(
505 Group_Control_Box_Shadow::get_type(),
506 [
507 'name' => 'tabs_title_box_shadow',
508 'label' => esc_html__( 'Shadow', 'elementor' ),
509 'separator' => 'after',
510 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
511 ]
512 );
513
514 $this->end_controls_tab();
515
516 $this->start_controls_tab(
517 'tabs_title_hover',
518 [
519 'label' => esc_html__( 'Hover', 'elementor' ),
520 ]
521 );
522
523 $this->add_group_control(
524 Group_Control_Background::get_type(),
525 [
526 'name' => 'tabs_title_background_color_hover',
527 'types' => [ 'classic', 'gradient' ],
528 'exclude' => [ 'image' ],
529 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
530 'fields_options' => [
531 'background' => [
532 'default' => 'classic',
533 ],
534 'color' => [
535 'global' => [
536 'default' => Global_Colors::COLOR_ACCENT,
537 ],
538 'label' => esc_html__( 'Background Color', 'elementor' ),
539 'selectors' => [
540 '{{SELECTOR}}' => 'background: {{VALUE}};',
541 ],
542 ],
543 ],
544 ]
545 );
546
547 $this->add_group_control(
548 Group_Control_Border::get_type(),
549 [
550 'name' => 'tabs_title_border_hover',
551 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
552 'fields_options' => [
553 'color' => [
554 'label' => esc_html__( 'Border Color', 'elementor' ),
555 ],
556 'width' => [
557 'label' => esc_html__( 'Border Width', 'elementor' ),
558 ],
559 ],
560 ]
561 );
562
563 $this->add_group_control(
564 Group_Control_Box_Shadow::get_type(),
565 [
566 'name' => 'tabs_title_box_shadow_hover',
567 'label' => esc_html__( 'Shadow', 'elementor' ),
568 'separator' => 'after',
569 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
570 ]
571 );
572
573 $this->add_control(
574 'hover_animation',
575 [
576 'label' => esc_html__( 'Hover Animation', 'elementor' ),
577 'type' => Controls_Manager::HOVER_ANIMATION,
578 ]
579 );
580
581 $this->add_control(
582 'tabs_title_transition_duration',
583 [
584 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
585 'type' => Controls_Manager::SLIDER,
586 'selectors' => [
587 '{{WRAPPER}}' => '--n-tabs-title-transition: {{SIZE}}s',
588 ],
589 'range' => [
590 'px' => [
591 'max' => 3,
592 'step' => 0.1,
593 ],
594 ],
595 ]
596 );
597
598 $this->end_controls_tab();
599
600 $this->start_controls_tab(
601 'tabs_title_active',
602 [
603 'label' => esc_html__( 'Active', 'elementor' ),
604 ]
605 );
606
607 $this->add_group_control(
608 Group_Control_Background::get_type(),
609 [
610 'name' => 'tabs_title_background_color_active',
611 'types' => [ 'classic', 'gradient' ],
612 'exclude' => [ 'image' ],
613 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
614 'fields_options' => [
615 'background' => [
616 'default' => 'classic',
617 ],
618 'color' => [
619 'global' => [
620 'default' => Global_Colors::COLOR_ACCENT,
621 ],
622 'label' => esc_html__( 'Background Color', 'elementor' ),
623 'selectors' => [
624 '{{SELECTOR}}' => 'background: {{VALUE}};',
625 ],
626 ],
627 ],
628 ]
629 );
630
631 $this->add_group_control(
632 Group_Control_Border::get_type(),
633 [
634 'name' => 'tabs_title_border_active',
635 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
636 'fields_options' => [
637 'color' => [
638 'label' => esc_html__( 'Border Color', 'elementor' ),
639 ],
640 'width' => [
641 'label' => esc_html__( 'Border Width', 'elementor' ),
642 ],
643 ],
644 ]
645 );
646
647 $this->add_group_control(
648 Group_Control_Box_Shadow::get_type(),
649 [
650 'name' => 'tabs_title_box_shadow_active',
651 'label' => esc_html__( 'Shadow', 'elementor' ),
652 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
653 ]
654 );
655
656 $this->end_controls_tab();
657
658 $this->end_controls_tabs();
659
660 $this->add_responsive_control(
661 'tabs_title_border_radius',
662 [
663 'label' => esc_html__( 'Border Radius', 'elementor' ),
664 'type' => Controls_Manager::DIMENSIONS,
665 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
666 'separator' => 'before',
667 'selectors' => [
668 '{{WRAPPER}}' => '--n-tabs-title-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
669 ],
670 ]
671 );
672
673 $this->add_responsive_control(
674 'padding',
675 [
676 'label' => esc_html__( 'Padding', 'elementor' ),
677 'type' => Controls_Manager::DIMENSIONS,
678 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
679 'selectors' => [
680 '{{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;",
681 ],
682 ]
683 );
684
685 $this->end_controls_section();
686
687 $this->start_controls_section( 'section_title_style', [
688 'label' => esc_html__( 'Titles', 'elementor' ),
689 'tab' => Controls_Manager::TAB_STYLE,
690 ] );
691
692 $this->add_group_control( Group_Control_Typography::get_type(), [
693 'name' => 'title_typography',
694 'global' => [
695 'default' => Global_Typography::TYPOGRAPHY_ACCENT,
696 ],
697 'selector' => "{$heading_selector} > :is( .e-n-tab-title > .e-n-tab-title-text, .e-n-tab-title )",
698 'fields_options' => [
699 'font_size' => [
700 'selectors' => [
701 '{{WRAPPER}}' => '--n-tabs-title-font-size: {{SIZE}}{{UNIT}}',
702 ],
703 ],
704 ],
705 ] );
706
707 $this->start_controls_tabs( 'title_style' );
708
709 $this->start_controls_tab(
710 'title_normal',
711 [
712 'label' => esc_html__( 'Normal', 'elementor' ),
713 ]
714 );
715
716 $this->add_control(
717 'title_text_color',
718 [
719 'label' => esc_html__( 'Color', 'elementor' ),
720 'type' => Controls_Manager::COLOR,
721 'selectors' => [
722 '{{WRAPPER}}' => '--n-tabs-title-color: {{VALUE}}',
723 ],
724 ]
725 );
726
727 $this->add_group_control(
728 Group_Control_Text_Shadow::get_type(),
729 [
730 'name' => 'title_text_shadow',
731 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
732 'fields_options' => [
733 'text_shadow_type' => [
734 'label' => esc_html_x( 'Shadow', 'Text Shadow Control', 'elementor' ),
735 ],
736 ],
737 ]
738 );
739
740 $this->add_group_control(
741 Group_Control_Text_Stroke::get_type(),
742 [
743 'name' => 'title_text_stroke',
744 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover ) :is( span, a, i )",
745 'fields_options' => [
746 'text_stroke_type' => [
747 'label' => esc_html__( 'Stroke', 'elementor' ),
748 ],
749 ],
750 ]
751 );
752
753 $this->end_controls_tab();
754
755 $this->start_controls_tab(
756 'title_hover',
757 [
758 'label' => esc_html__( 'Hover', 'elementor' ),
759 ]
760 );
761
762 $this->add_control(
763 'title_text_color_hover',
764 [
765 'label' => esc_html__( 'Color', 'elementor' ),
766 'type' => Controls_Manager::COLOR,
767 'selectors' => [
768 '{{WRAPPER}} [data-touch-mode="false"] .e-n-tab-title[aria-selected="false"]:hover' => '--n-tabs-title-color-hover: {{VALUE}}',
769 ],
770 ]
771 );
772
773 $this->add_group_control(
774 Group_Control_Text_Shadow::get_type(),
775 [
776 'name' => 'title_text_shadow_hover',
777 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
778 'fields_options' => [
779 'text_shadow_type' => [
780 'label' => esc_html_x( 'Shadow', 'Text Shadow Control', 'elementor' ),
781 ],
782 ],
783
784 ]
785 );
786
787 $this->add_group_control(
788 Group_Control_Text_Stroke::get_type(),
789 [
790 'name' => 'title_text_stroke_hover',
791 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover :is( span, a, i )",
792 'fields_options' => [
793 'text_stroke_type' => [
794 'label' => esc_html__( 'Stroke', 'elementor' ),
795 ],
796 ],
797 ]
798 );
799
800 $this->end_controls_tab();
801
802 $this->start_controls_tab(
803 'title_active',
804 [
805 'label' => esc_html__( 'Active', 'elementor' ),
806 ]
807 );
808
809 $this->add_control(
810 'title_text_color_active',
811 [
812 'label' => esc_html__( 'Color', 'elementor' ),
813 'type' => Controls_Manager::COLOR,
814 'selectors' => [
815 '{{WRAPPER}}' => '--n-tabs-title-color-active: {{VALUE}}',
816 ],
817 ]
818 );
819
820 $this->add_group_control(
821 Group_Control_Text_Shadow::get_type(),
822 [
823 'name' => 'title_text_shadow_active',
824 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
825 'fields_options' => [
826 'text_shadow_type' => [
827 'label' => esc_html_x( 'Shadow', 'Text Shadow Control', 'elementor' ),
828 ],
829 ],
830 ]
831 );
832
833 $this->add_group_control(
834 Group_Control_Text_Stroke::get_type(),
835 [
836 'name' => 'title_text_stroke_active',
837 '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 )",
838 'fields_options' => [
839 'text_stroke_type' => [
840 'label' => esc_html__( 'Stroke', 'elementor' ),
841 ],
842 ],
843 ]
844 );
845
846 $this->end_controls_tab();
847
848 $this->end_controls_tabs();
849
850 $this->end_controls_section();
851
852 $this->start_controls_section( 'icon_section_style', [
853 'label' => esc_html__( 'Icon', 'elementor' ),
854 'tab' => Controls_Manager::TAB_STYLE,
855 ] );
856
857 $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;';
858 $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;';
859 $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;';
860 $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;';
861
862 $this->add_responsive_control( 'icon_position', [
863 'label' => esc_html__( 'Position', 'elementor' ),
864 'type' => Controls_Manager::CHOOSE,
865 'options' => [
866 'block-start' => [
867 'title' => esc_html__( 'Above', 'elementor' ),
868 'icon' => 'eicon-v-align-top',
869 ],
870 'inline-end' => [
871 'title' => esc_html__( 'After', 'elementor' ),
872 'icon' => 'eicon-h-align-' . $end,
873 ],
874 'block-end' => [
875 'title' => esc_html__( 'Below', 'elementor' ),
876 'icon' => 'eicon-v-align-bottom',
877 ],
878 'inline-start' => [
879 'title' => esc_html__( 'Before', 'elementor' ),
880 'icon' => 'eicon-h-align-' . $start,
881 ],
882 ],
883 'selectors_dictionary' => [
884 // The toggle variables for 'align items' and 'justify content' have been added to separate the styling of the two 'flex direction' modes.
885 'block-start' => $styling_block_start,
886 'inline-end' => $styling_inline_end,
887 'block-end' => $styling_block_end,
888 'inline-start' => $styling_inline_start,
889 // Styling duplication for BC reasons.
890 'top' => $styling_block_start,
891 'bottom' => $styling_block_end,
892 'start' => $styling_inline_start,
893 'end' => $styling_inline_end,
894 ],
895 'selectors' => [
896 '{{WRAPPER}}' => '{{VALUE}}',
897 ],
898 ] );
899
900 $this->add_responsive_control( 'icon_size', [
901 'label' => esc_html__( 'Size', 'elementor' ),
902 'type' => Controls_Manager::SLIDER,
903 'range' => [
904 'px' => [
905 'min' => 0,
906 'max' => 100,
907 ],
908 'em' => [
909 'min' => 0,
910 'max' => 10,
911 'step' => 0.1,
912 ],
913 'rem' => [
914 'min' => 0,
915 'max' => 10,
916 'step' => 0.1,
917 ],
918 ],
919 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ],
920 'selectors' => [
921 '{{WRAPPER}}' => '--n-tabs-icon-size: {{SIZE}}{{UNIT}}',
922 ],
923 ] );
924
925 $this->add_responsive_control( 'icon_spacing', [
926 'label' => esc_html__( 'Spacing', 'elementor' ),
927 'type' => Controls_Manager::SLIDER,
928 'range' => [
929 'px' => [
930 'min' => 0,
931 'max' => 400,
932 ],
933 'vw' => [
934 'min' => 0,
935 'max' => 50,
936 'step' => 0.1,
937 ],
938 ],
939 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ],
940 'selectors' => [
941 '{{WRAPPER}}' => '--n-tabs-icon-gap: {{SIZE}}{{UNIT}}',
942 ],
943 ] );
944
945 $this->start_controls_tabs( 'icon_style_states' );
946
947 $this->start_controls_tab(
948 'icon_section_normal',
949 [
950 'label' => esc_html__( 'Normal', 'elementor' ),
951 ]
952 );
953
954 $this->add_control( 'icon_color', [
955 'label' => esc_html__( 'Color', 'elementor' ),
956 'type' => Controls_Manager::COLOR,
957 'selectors' => [
958 '{{WRAPPER}}' => '--n-tabs-icon-color: {{VALUE}};',
959 ],
960 ] );
961
962 $this->end_controls_tab();
963
964 $this->start_controls_tab(
965 'icon_section_hover',
966 [
967 'label' => esc_html__( 'Hover', 'elementor' ),
968 ]
969 );
970
971 $this->add_control( 'icon_color_hover', [
972 'label' => esc_html__( 'Color', 'elementor' ),
973 'type' => Controls_Manager::COLOR,
974 'selectors' => [
975 '{{WRAPPER}} [data-touch-mode="false"] .e-n-tab-title[aria-selected="false"]:hover' => '--n-tabs-icon-color-hover: {{VALUE}};',
976 ],
977 ] );
978
979 $this->end_controls_tab();
980
981 $this->start_controls_tab(
982 'icon_section_active',
983 [
984 'label' => esc_html__( 'Active', 'elementor' ),
985 ]
986 );
987
988 $this->add_control( 'icon_color_active', [
989 'label' => esc_html__( 'Color', 'elementor' ),
990 'type' => Controls_Manager::COLOR,
991 'selectors' => [
992 '{{WRAPPER}}' => '--n-tabs-icon-color-active: {{VALUE}};',
993 ],
994 ] );
995
996 $this->end_controls_tab();
997
998 $this->end_controls_tabs();
999
1000 $this->end_controls_section();
1001
1002 $this->start_controls_section( 'section_box_style', [
1003 'label' => esc_html__( 'Content', 'elementor' ),
1004 'tab' => Controls_Manager::TAB_STYLE,
1005 ] );
1006
1007 $this->add_group_control(
1008 Group_Control_Background::get_type(),
1009 [
1010 'name' => 'box_background_color',
1011 'types' => [ 'classic', 'gradient' ],
1012 'exclude' => [ 'image' ],
1013 'selector' => $content_selector,
1014 'fields_options' => [
1015 'color' => [
1016 'label' => esc_html__( 'Background Color', 'elementor' ),
1017 ],
1018 ],
1019 ]
1020 );
1021
1022 $this->add_group_control(
1023 Group_Control_Border::get_type(),
1024 [
1025 'name' => 'box_border',
1026 'selector' => $content_selector,
1027 'fields_options' => [
1028 'color' => [
1029 'label' => esc_html__( 'Border Color', 'elementor' ),
1030 ],
1031 'width' => [
1032 'label' => esc_html__( 'Border Width', 'elementor' ),
1033 ],
1034 ],
1035 ]
1036 );
1037
1038 $this->add_responsive_control(
1039 'box_border_radius',
1040 [
1041 'label' => esc_html__( 'Border Radius', 'elementor' ),
1042 'type' => Controls_Manager::DIMENSIONS,
1043 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
1044 'selectors' => [
1045 $content_selector => '--border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1046 ],
1047 ]
1048 );
1049
1050 $this->add_group_control(
1051 Group_Control_Box_Shadow::get_type(),
1052 [
1053 'name' => 'box_shadow_box_shadow',
1054 'selector' => $content_selector,
1055 'condition' => [
1056 'box_height!' => 'height',
1057 ],
1058 ]
1059 );
1060
1061 $this->add_responsive_control(
1062 'box_padding',
1063 [
1064 'label' => esc_html__( 'Padding', 'elementor' ),
1065 'type' => Controls_Manager::DIMENSIONS,
1066 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
1067 'selectors' => [
1068 $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;",
1069 ],
1070 ]
1071 );
1072
1073 $this->end_controls_section();
1074 }
1075
1076 protected function render_tab_titles_html( $item_settings ): string {
1077 $setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $item_settings['index'] );
1078 $title = $item_settings['item']['tab_title'];
1079 $css_classes = [ 'e-n-tab-title' ];
1080
1081 if ( $item_settings['settings']['hover_animation'] ) {
1082 $css_classes[] = 'elementor-animation-' . $item_settings['settings']['hover_animation'];
1083 }
1084
1085 $this->add_render_attribute( $setting_key, [
1086 'id' => $item_settings['tab_id'],
1087 'class' => $css_classes,
1088 'aria-selected' => 1 === $item_settings['tab_count'] ? 'true' : 'false',
1089 'data-tab-index' => $item_settings['tab_count'],
1090 'role' => 'tab',
1091 'tabindex' => 1 === $item_settings['tab_count'] ? '0' : '-1',
1092 'aria-controls' => $item_settings['container_id'],
1093 'style' => '--n-tabs-title-order: ' . $item_settings['tab_count'] . ';',
1094 ] );
1095
1096 $render_attributes = $this->get_render_attribute_string( $setting_key );
1097 $text_class = $this->get_render_attribute_string( 'tab-title-text' );
1098 $icon_class = $this->get_render_attribute_string( 'tab-icon' );
1099
1100 $icon_html = Icons_Manager::try_get_icon_html( $item_settings['item']['tab_icon'], [ 'aria-hidden' => 'true' ] );
1101 $icon_active_html = $icon_html;
1102
1103 if ( $this->is_active_icon_exist( $item_settings['item'] ) ) {
1104 $icon_active_html = Icons_Manager::try_get_icon_html( $item_settings['item']['tab_icon_active'], [ 'aria-hidden' => 'true' ] );
1105 }
1106
1107 ob_start();
1108 ?>
1109 <button <?php echo $render_attributes; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1110 <span <?php echo $icon_class; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1111 <?php echo $icon_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1112 <?php echo $icon_active_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1113 </span>
1114 <span <?php echo $text_class; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1115 <?php echo wp_kses_post( $title ); ?>
1116 </span>
1117 </button>
1118 <?php
1119 return ob_get_clean();
1120 }
1121
1122 protected function render_tab_containers_html( $item_settings ): string {
1123 ob_start();
1124 $this->print_child( $item_settings['index'], $item_settings );
1125 return ob_get_clean();
1126 }
1127
1128
1129 /**
1130 * Print the content area.
1131 *
1132 * @param int $index
1133 * @param array $item_settings
1134 */
1135 public function print_child( $index, $item_settings = [] ) {
1136 $children = $this->get_children();
1137 $child_ids = [];
1138
1139 foreach ( $children as $child ) {
1140 $child_ids[] = $child->get_id();
1141 }
1142
1143 // Add data-tab-index attribute to the content area.
1144 $add_attribute_to_container = function ( $should_render, $container ) use ( $item_settings, $child_ids ) {
1145 if ( in_array( $container->get_id(), $child_ids ) ) {
1146 $this->add_attributes_to_container( $container, $item_settings );
1147 }
1148
1149 return $should_render;
1150 };
1151
1152 add_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container, 10, 3 );
1153 $children[ $index ]->print_element();
1154 remove_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container );
1155 }
1156
1157 protected function add_attributes_to_container( $container, $item_settings ) {
1158 $container->add_render_attribute( '_wrapper', [
1159 'id' => $item_settings['container_id'],
1160 'role' => 'tabpanel',
1161 'aria-labelledby' => $item_settings['tab_id'],
1162 'data-tab-index' => $item_settings['tab_count'],
1163 'style' => '--n-tabs-title-order: ' . $item_settings['tab_count'] . ';',
1164 'class' => 0 === $item_settings['index'] ? 'e-active' : '',
1165 ] );
1166 }
1167
1168 protected function render() {
1169 $settings = $this->get_settings_for_display();
1170 $widget_number = substr( $this->get_id_int(), 0, 3 );
1171
1172 if ( ! empty( $settings['link'] ) ) {
1173 $this->add_link_attributes( 'elementor-tabs', $settings['link'] );
1174 }
1175
1176 $this->add_render_attribute( 'elementor-tabs', [
1177 'class' => 'e-n-tabs',
1178 'data-widget-number' => $widget_number,
1179 'aria-label' => esc_html__( 'Tabs. Open items with Enter or Space, close with Escape and navigate using the Arrow keys.', 'elementor' ),
1180 ] );
1181
1182 $this->add_render_attribute( 'tab-title-text', 'class', 'e-n-tab-title-text' );
1183 $this->add_render_attribute( 'tab-icon', 'class', 'e-n-tab-icon' );
1184 $this->add_render_attribute( 'tab-icon-active', 'class', [ 'e-n-tab-icon' ] );
1185
1186 $tab_titles_html = '';
1187 $tab_containers_html = '';
1188
1189 foreach ( $settings['tabs'] as $index => $item ) {
1190 $tab_count = $index + 1;
1191
1192 $tab_id = empty( $item['element_id'] )
1193 ? 'e-n-tabs-title-' . $widget_number . $tab_count
1194 : $item['element_id'];
1195
1196 $item_settings = [
1197 'index' => $index,
1198 'tab_count' => $tab_count,
1199 'tab_id' => $tab_id,
1200 'container_id' => 'e-n-tab-content-' . $widget_number . $tab_count,
1201 'widget_number' => $widget_number,
1202 'item' => $item,
1203 'settings' => $settings,
1204 ];
1205
1206 $tab_titles_html .= $this->render_tab_titles_html( $item_settings );
1207 $tab_containers_html .= $this->render_tab_containers_html( $item_settings );
1208 }
1209 ?>
1210 <div <?php $this->print_render_attribute_string( 'elementor-tabs' ); ?>>
1211 <div class="e-n-tabs-heading" role="tablist">
1212 <?php echo $tab_titles_html;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1213 </div>
1214 <div class="e-n-tabs-content">
1215 <?php echo $tab_containers_html;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1216 </div>
1217 </div>
1218 <?php
1219 }
1220
1221 protected function content_template() {
1222 ?>
1223 <# const elementUid = view.getIDInt().toString().substr( 0, 3 ); #>
1224 <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' ); ?>">
1225 <# if ( settings['tabs'] ) { #>
1226 <div class="e-n-tabs-heading" role="tablist">
1227 <# _.each( settings['tabs'], function( item, index ) {
1228 const tabCount = index + 1,
1229 tabUid = elementUid + tabCount,
1230 tabWrapperKey = tabUid,
1231 tabTitleKey = 'tab-title-' + tabUid,
1232 tabIconKey = 'tab-icon-' + tabUid,
1233 tabIcon = elementor.helpers.renderIcon( view, item.tab_icon, { 'aria-hidden': true }, 'i' , 'object' ),
1234 hoverAnimationClass = settings['hover_animation'] ? `elementor-animation-${ settings['hover_animation'] }` : '';
1235
1236 let tabActiveIcon = tabIcon,
1237 tabId = 'e-n-tab-title-' + tabUid;
1238
1239 if ( '' !== item.tab_icon_active.value ) {
1240 tabActiveIcon = elementor.helpers.renderIcon( view, item.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' );
1241 }
1242
1243 if ( '' !== item.element_id ) {
1244 tabId = item.element_id;
1245 }
1246
1247 view.addRenderAttribute( tabWrapperKey, {
1248 'id': tabId,
1249 'class': [ 'e-n-tab-title',hoverAnimationClass ],
1250 'data-tab-index': tabCount,
1251 'role': 'tab',
1252 'aria-selected': 1 === tabCount ? 'true' : 'false',
1253 'tabindex': 1 === tabCount ? '0' : '-1',
1254 'aria-controls': 'e-n-tab-content-' + tabUid,
1255 'style': '--n-tabs-title-order: ' + tabCount + ';',
1256 } );
1257
1258 view.addRenderAttribute( tabTitleKey, {
1259 'class': [ 'e-n-tab-title-text' ],
1260 'data-binding-type': 'repeater-item',
1261 'data-binding-repeater-name': 'tabs',
1262 'data-binding-setting': [ 'tab_title' ],
1263 'data-binding-index': tabCount,
1264 } );
1265
1266 view.addRenderAttribute( tabIconKey, {
1267 'class': [ 'e-n-tab-icon' ],
1268 'data-binding-type': 'repeater-item',
1269 'data-binding-repeater-name': 'tabs',
1270 'data-binding-setting': [ 'tab_icon.value', 'tab_icon_active.value' ],
1271 'data-binding-index': tabCount,
1272 } );
1273 #>
1274 <button {{{ view.getRenderAttributeString( tabWrapperKey ) }}}>
1275 <span {{{ view.getRenderAttributeString( tabIconKey ) }}}>{{{ tabIcon.value }}}{{{ tabActiveIcon.value }}}</span>
1276 <span {{{ view.getRenderAttributeString( tabTitleKey ) }}}>{{{ item.tab_title }}}</span>
1277 </button>
1278 <# } ); #>
1279 </div>
1280 <div class="e-n-tabs-content"></div>
1281 <# } #>
1282 </div>
1283 <?php
1284 }
1285
1286 /**
1287 * @param $item
1288 * @return bool
1289 */
1290 private function is_active_icon_exist( $item ) {
1291 return array_key_exists( 'tab_icon_active', $item ) && ! empty( $item['tab_icon_active'] ) && ! empty( $item['tab_icon_active']['value'] );
1292 }
1293 }
1294