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

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