PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.2.3
UiCore Elements – Free widgets and templates for Elementor v1.2.3
1.3.17 1.3.16 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 All 41 releases
uicore-elements / includes / widgets / tabs.php

tabs.php in UiCore Elements – Free widgets and templates for Elementor 1.2.3, at includes/widgets/tabs.php

1,624 lines 52.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace UiCoreElements;
3
4 use Elementor\Controls_Manager;
5 use Elementor\Repeater;
6 use Elementor\Plugin;
7 use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
8 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
9 use Elementor\Group_Control_Background;
10 use Elementor\Group_Control_Border;
11 use Elementor\Group_Control_Box_Shadow;
12 use Elementor\Group_Control_Typography;
13 use Elementor\Icons_Manager;
14 use Elementor\Modules\NestedElements\Controls\Control_Nested_Repeater;
15
16 defined('ABSPATH') || exit();
17
18 /**
19 * Tabs
20 *
21 * @author Lucas Marini Falbo <lucas@uicore.co>
22 * @since 1.0.6
23 */
24
25 class Tabs extends UiCoreNestedWidget {
26
27 public function get_name() {
28 return 'uicore-tabs';
29 }
30 public function get_title() {
31 return esc_html__( 'Tabs', 'uicore-elements' );
32 }
33 public function get_icon() {
34 return 'eicon-tabs ui-e-widget';
35 }
36 public function get_categories()
37 {
38 return ['uicore'];
39 }
40 public function get_keywords() {
41 return [ 'tabs', 'tab', 'content', 'nested' ];
42 }
43 public function get_styles()
44 {
45 return ['tabs'];
46 }
47 public function get_scripts()
48 {
49 return ['tabs'];
50 }
51 // TODO: remove or set as false, after 3.30, when the full deprecation of widget innet wrapper is ready
52 public function has_widget_inner_wrapper(): bool {
53 return true;
54 }
55
56 // Nested required functions
57 protected function tab_content_container( int $index ) {
58 return [
59 'elType' => 'container',
60 'settings' => [
61 /* translators: %s: Tab index */
62 '_title' => sprintf( __( 'Tab #%s', 'uicore-elements' ), $index ),
63 'content_width' => 'full',
64 ],
65 ];
66 }
67 protected function get_default_children_elements() {
68 return [
69 $this->tab_content_container( 1 ),
70 $this->tab_content_container( 2 ),
71 $this->tab_content_container( 3 ),
72 ];
73 }
74 protected function get_default_repeater_title_setting_key() {
75 return 'tab_title';
76 }
77 protected function get_default_children_title() {
78 /* translators: %d: Tab index */
79 return esc_html__( 'Tab #%d', 'uicore-elements' );
80 }
81 protected function get_default_children_placeholder_selector() {
82 return '.ui-e-tabs-content';
83 }
84
85 protected function register_controls() {
86
87 if( !Plugin::$instance->experiments->is_feature_active('nested-elements') ){
88 $this->nesting_fallback('controls');
89 return;
90 }
91
92 // Helper properties
93 $start = is_rtl() ? 'right' : 'left';
94 $end = is_rtl() ? 'left' : 'right';
95 $start_logical = is_rtl() ? 'end' : 'start';
96 $end_logical = is_rtl() ? 'start' : 'end';
97 $heading_selector = '{{WRAPPER}} > .elementor-widget-container > .ui-e-tabs > .ui-e-tabs-heading'; // TODO: .elementor-widget-container will be gone soon
98 $content_selector = ':where( {{WRAPPER}} > .elementor-widget-container > .ui-e-tabs > .ui-e-tabs-content ) > .e-con'; // TODO: .elementor-widget-container will be gone soon
99
100 $this->start_controls_section(
101 'section_tabs',
102 [
103 'label' => esc_html__( 'Tabs', 'uicore-elements' ),
104 'tab' => Controls_Manager::TAB_CONTENT,
105 ]
106 );
107
108 $repeater = new Repeater();
109
110 $repeater->add_control( 'tab_title', [
111 'label' => esc_html__( 'Title', 'uicore-elements' ),
112 'type' => Controls_Manager::TEXT,
113 'default' => esc_html__( 'Tab Title', 'uicore-elements' ),
114 'placeholder' => esc_html__( 'Tab Title', 'uicore-elements' ),
115 'label_block' => true,
116 'dynamic' => [
117 'active' => true,
118 ],
119 ] );
120
121 $repeater->add_control( 'tab_description', [
122 'label' => esc_html__( 'Description', 'uicore-elements' ),
123 'type' => Controls_Manager::TEXTAREA,
124 'rows' => 2,
125 'placeholder' => esc_html__( 'Tab Title', 'uicore-elements' ),
126 'label_block' => true,
127 'dynamic' => [
128 'active' => true,
129 ],
130 ] );
131
132 $repeater->add_control(
133 'tab_icon',
134 [
135 'label' => esc_html__( 'Icon', 'uicore-elements' ),
136 'type' => Controls_Manager::ICONS,
137 'fa4compatibility' => 'icon',
138 'skin' => 'inline',
139 'label_block' => false,
140 ]
141 );
142
143 $repeater->add_control(
144 'tab_icon_active',
145 [
146 'label' => esc_html__( 'Active Icon', 'uicore-elements' ),
147 'type' => Controls_Manager::ICONS,
148 'fa4compatibility' => 'icon',
149 'skin' => 'inline',
150 'label_block' => false,
151 'condition' => [
152 'tab_icon[value]!' => '',
153 ],
154 ]
155 );
156
157 $repeater->add_control(
158 'tab_id',
159 [
160 'label' => esc_html__( 'CSS ID', 'uicore-elements' ),
161 'type' => Controls_Manager::TEXT,
162 'default' => '',
163 'ai' => [
164 'active' => false,
165 ],
166 'dynamic' => [
167 'active' => true,
168 ],
169 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'uicore-elements' ),
170 'style_transfer' => false,
171 'classes' => 'elementor-control-direction-ltr',
172 ]
173 );
174
175 $this->add_control( 'tabs', [
176 'label' => esc_html__( 'Tabs Items', 'uicore-elements' ),
177 'type' => Control_Nested_Repeater::CONTROL_TYPE,
178 'fields' => $repeater->get_controls(),
179 'default' => [
180 [
181 'tab_title' => esc_html__( 'Tab #1', 'uicore-elements' ),
182 ],
183 [
184 'tab_title' => esc_html__( 'Tab #2', 'uicore-elements' ),
185 ],
186 [
187 'tab_title' => esc_html__( 'Tab #3', 'uicore-elements' ),
188 ],
189 ],
190 'title_field' => '{{{ tab_title }}}',
191 'button_text' => 'Add Tab',
192 ] );
193
194 // Tabs position and alignment group values
195 $styling_block_start = '--ui-e-tabs-direction: column; --ui-e-tabs-head-direction: row; --ui-e-tabs-head-width: initial; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-shrink: initial;';
196 $styling_block_end = '--ui-e-tabs-direction: column-reverse; --ui-e-tabs-head-direction: row; --ui-e-tabs-head-width: initial; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-shrink: initial;';
197 $styling_inline_end = '--ui-e-tabs-direction: row-reverse; --ui-e-tabs-head-direction: column; --ui-e-tabs-head-width: 240px; --ui-e-tabs-title-flex-basis: initial; --ui-e-tabs-title-flex-shrink: 0; --ui-e-tabs-title-width: 100%';
198 $styling_inline_start = '--ui-e-tabs-direction: row; --ui-e-tabs-head-direction: column; --ui-e-tabs-head-width: 240px; --ui-e-tabs-title-flex-basis: initial; --ui-e-tabs-title-flex-shrink: 0; --ui-e-tabs-title-width: 100%';
199
200 $this->add_responsive_control( 'tabs_direction', [
201 'label' => esc_html__( 'Tabs Direction', 'uicore-elements' ),
202 'type' => Controls_Manager::CHOOSE,
203 'options' => [
204 'block-start' => [
205 'title' => esc_html__( 'Above', 'uicore-elements' ),
206 'icon' => 'eicon-v-align-top',
207 ],
208 'block-end' => [
209 'title' => esc_html__( 'Below', 'uicore-elements' ),
210 'icon' => 'eicon-v-align-bottom',
211 ],
212 'inline-end' => [
213 'title' => esc_html__( 'After', 'uicore-elements' ),
214 'icon' => 'eicon-h-align-' . $end,
215 ],
216 'inline-start' => [
217 'title' => esc_html__( 'Before', 'uicore-elements' ),
218 'icon' => 'eicon-h-align-' . $start,
219 ],
220 ],
221 'default' => 'block-start',
222 'separator' => 'before',
223 'selectors_dictionary' => [
224 'block-start' => $styling_block_start,
225 'block-end' => $styling_block_end,
226 'inline-end' => $styling_inline_end,
227 'inline-start' => $styling_inline_start,
228 ],
229 'selectors' => [
230 '{{WRAPPER}}' => '{{VALUE}}',
231 ],
232 ] );
233
234 $this->add_responsive_control( 'tabs_width', [
235 'label' => esc_html__( 'Tabs Width', 'uicore-elements' ),
236 'type' => Controls_Manager::SLIDER,
237 'range' => [
238 '%' => [
239 'min' => 10,
240 'max' => 50,
241 ],
242 'px' => [
243 'min' => 20,
244 'max' => 600,
245 ],
246 ],
247 'default' => [
248 'unit' => '%',
249 ],
250 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
251 'selectors' => [
252 '{{WRAPPER}}' => '--ui-e-tabs-head-width: {{SIZE}}{{UNIT}}',
253 ],
254 'condition' => [
255 'tabs_direction' => [
256 'inline-start',
257 'inline-end',
258 ],
259 ],
260 ] );
261
262 $this->add_responsive_control( 'tabs_justify_horizontal', [
263 'label' => esc_html__( 'Justify', 'uicore-elements' ),
264 'type' => Controls_Manager::CHOOSE,
265 'options' => [
266 'start' => [
267 'title' => esc_html__( 'Start', 'uicore-elements' ),
268 'icon' => "eicon-align-$start_logical-h",
269 ],
270 'center' => [
271 'title' => esc_html__( 'Center', 'uicore-elements' ),
272 'icon' => 'eicon-align-center-h',
273 ],
274 'end' => [
275 'title' => esc_html__( 'End', 'uicore-elements' ),
276 'icon' => "eicon-align-$end_logical-h",
277 ],
278 'stretch' => [
279 'title' => esc_html__( 'Stretch', 'uicore-elements' ),
280 'icon' => 'eicon-align-stretch-h',
281 ],
282 ],
283 'selectors_dictionary' => [
284 'start' => 'justify-content: flex-start; --ui-e-tabs-title-flex-width: initial; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-title-flex-grow: 0;',
285 'center' => 'justify-content: center; --ui-e-tabs-title-flex-width: initial; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-title-flex-grow: 0;',
286 'end' => 'justify-content: flex-end; --ui-e-tabs-title-flex-width: initial; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-title-flex-grow: 0;',
287 'stretch' => 'justify-content: initial; --ui-e-tabs-title-flex-width: 100%; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-title-flex-grow: 1;',
288 ],
289 'selectors' => [
290 '{{WRAPPER}} .ui-e-tabs-heading' => '{{VALUE}}',
291 ],
292 'condition' => [
293 'tabs_direction' => [
294 'block-start',
295 'block-end',
296 ],
297 ],
298 'frontend_available' => true,
299 ] );
300
301 $this->add_responsive_control( 'tabs_justify_vertical', [
302 'label' => esc_html__( 'Tabs alignment', 'uicore-elements' ),
303 'type' => Controls_Manager::CHOOSE,
304 'options' => [
305 'start' => [
306 'title' => esc_html__( 'Start', 'uicore-elements' ),
307 'icon' => 'eicon-align-start-v',
308 ],
309 'center' => [
310 'title' => esc_html__( 'Center', 'uicore-elements' ),
311 'icon' => 'eicon-align-center-v',
312 ],
313 'end' => [
314 'title' => esc_html__( 'End', 'uicore-elements' ),
315 'icon' => 'eicon-align-end-v',
316 ],
317 'stretch' => [
318 'title' => esc_html__( 'Stretch', 'uicore-elements' ),
319 'icon' => 'eicon-align-stretch-v',
320 ],
321 ],
322 'selectors_dictionary' => [
323 'start' => 'justify-content: flex-start; --ui-e-tabs-title-height: initial; --ui-e-tabs-title-justify-content: initial; --ui-e-tabs-heading-wrap: wrap; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-grow: 0;',
324 'center' => 'justify-content: center; --ui-e-tabs-title-height: initial; --ui-e-tabs-title-justify-content: initial; --ui-e-tabs-heading-wrap: wrap; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-grow: 0;',
325 'end' => 'justify-content: flex-end; --ui-e-tabs-title-height: initial; --ui-e-tabs-title-justify-content: initial; --ui-e-tabs-heading-wrap: wrap; --ui-e-tabs-title-flex-basis: content; --ui-e-tabs-title-flex-grow: 0;',
326 'stretch' => 'justify-content: flex-start; --ui-e-tabs-title-height: 100%; --ui-e-tabs-title-justify-content: center; --ui-e-tabs-heading-wrap: nowrap; --ui-e-tabs-title-flex-basis: auto; --ui-e-tabs-title-flex-grow: 1;',
327 ],
328 'selectors' => [
329 '{{WRAPPER}} .ui-e-tabs-heading' => '{{VALUE}}',
330 ],
331 'condition' => [
332 'tabs_direction' => [
333 'inline-start',
334 'inline-end',
335 ],
336 ],
337 ] );
338
339 $styling_icon_above = '--ui-e-tabs-title-direction: column; --ui-e-tabs-icon-order: initial;';
340 $styling_icon_before = '--ui-e-tabs-title-direction: row; --ui-e-tabs-icon-order: initial';
341 $styling_icon_after = '--ui-e-tabs-title-direction: row; --ui-e-tabs-icon-order: 1;';
342
343 $this->add_responsive_control( 'icon_position', [
344 'label' => esc_html__( 'Icon Position', 'uicore-elements' ),
345 'type' => Controls_Manager::CHOOSE,
346 'options' => [
347 'above' => [
348 'title' => esc_html__( 'Before', 'uicore-elements' ),
349 'icon' => 'eicon-v-align-top',
350 ],
351 'before' => [
352 'title' => esc_html__( 'Before', 'uicore-elements' ),
353 'icon' => 'eicon-h-align-' . $start,
354 ],
355 'after' => [
356 'title' => esc_html__( 'After', 'uicore-elements' ),
357 'icon' => 'eicon-h-align-' . $end,
358 ],
359 ],
360 'default' => 'before',
361 'selectors_dictionary' => [
362 'above' => $styling_icon_above,
363 'before' => $styling_icon_before,
364 'after' => $styling_icon_after,
365 ],
366 'separator' => 'before',
367 'selectors' => [
368 '{{WRAPPER}}' => '{{VALUE}}',
369 ],
370 ] );
371
372 $this->add_responsive_control( 'title_alignment', [
373 'label' => esc_html__( 'Content Alignment', 'uicore-elements' ),
374 'type' => Controls_Manager::CHOOSE,
375 'options' => [
376 'start' => [
377 'title' => esc_html__( 'Start', 'uicore-elements' ),
378 'icon' => 'eicon-text-align-left',
379 ],
380 'center' => [
381 'title' => esc_html__( 'Center', 'uicore-elements' ),
382 'icon' => 'eicon-text-align-center',
383 ],
384 'end' => [
385 'title' => esc_html__( 'End', 'uicore-elements' ),
386 'icon' => 'eicon-text-align-right',
387 ],
388 'justify' => [
389 'title' => esc_html__( 'Justify', 'uicore-elements' ),
390 'icon' => 'eicon-text-align-justify',
391 ],
392 ],
393 'selectors_dictionary' => [
394 'start' => '--ui-e-tabs-title-justify: flex-start; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: start;',
395 'center' => '--ui-e-tabs-title-justify: center; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: center;',
396 'end' => '--ui-e-tabs-title-justify: flex-end; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: end;',
397 'justify' => '--ui-e-tabs-title-justify: space-between; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: start;',
398 ],
399 'condition' => [
400 'icon_position!' => 'above',
401 ],
402 'selectors' => [
403 '{{WRAPPER}}' => '{{VALUE}}',
404 ],
405 ] );
406
407 $this->add_responsive_control( 'title_alignment_above', [
408 'label' => esc_html__( 'Content Alignment', 'uicore-elements' ),
409 'type' => Controls_Manager::CHOOSE,
410 'options' => [
411 'start' => [
412 'title' => esc_html__( 'Start', 'uicore-elements' ),
413 'icon' => 'eicon-text-align-left',
414 ],
415 'center' => [
416 'title' => esc_html__( 'Center', 'uicore-elements' ),
417 'icon' => 'eicon-text-align-center',
418 ],
419 'end' => [
420 'title' => esc_html__( 'End', 'uicore-elements' ),
421 'icon' => 'eicon-text-align-right',
422 ],
423 ],
424 'selectors_dictionary' => [
425 'start' => '--ui-e-tabs-title-justify: flex-start; --ui-e-tabs-title-align: flex-start; --ui-e-tabs-title-text-align: start;',
426 'center' => '--ui-e-tabs-title-justify: flex-start; --ui-e-tabs-title-align: center; --ui-e-tabs-title-text-align: center;',
427 'end' => '--ui-e-tabs-title-justify: flex-start; --ui-e-tabs-title-align: flex-end; --ui-e-tabs-title-text-align: end;',
428 ],
429 'condition' => [
430 'icon_position' => 'above',
431 ],
432 'selectors' => [
433 '{{WRAPPER}}' => '{{VALUE}}',
434 ],
435 ] );
436
437 $this->end_controls_section();
438
439 $this->start_controls_section(
440 'section_tabs_responsive',
441 [
442 'label' => esc_html__( 'Additional Settings', 'uicore-elements' ),
443 ]
444 );
445
446 // Build breakpoint options
447 $dropdown_options = [
448 'none' => esc_html__( 'None', 'uicore-elements' ),
449 ];
450 $excluded_breakpoints = [
451 'laptop',
452 'tablet_extra',
453 'widescreen',
454 ];
455
456 foreach ( Plugin::$instance->breakpoints->get_active_breakpoints() as $breakpoint_key => $breakpoint_instance ) {
457 // Exclude the larger breakpoints from the dropdown selector.
458 if ( in_array( $breakpoint_key, $excluded_breakpoints, true ) ) {
459 continue;
460 }
461
462 $dropdown_options[ $breakpoint_key ] = sprintf(
463 /* translators: 1: Breakpoint label, 2: `>` character, 3: Breakpoint value. */
464 esc_html__( '%1$s (%2$s %3$dpx)', 'uicore-elements' ),
465 $breakpoint_instance->get_label(),
466 '>',
467 $breakpoint_instance->get_value()
468 );
469 }
470
471 $this->add_control(
472 'breakpoint_selector',
473 [
474 'label' => esc_html__( 'Breakpoint', 'uicore-elements' ),
475 'type' => Controls_Manager::SELECT,
476 'description' => esc_html__( 'Note: Choose the breakpoint where tabs automatically switch to a vertical (“accordion”) layout.', 'uicore-elements' ),
477 'options' => $dropdown_options,
478 'default' => 'mobile',
479 'prefix_class' => 'ui-e-tabs-',
480 ]
481 );
482
483 $this->add_control(
484 'show_description',
485 [
486 'label' => esc_html__( 'Toggle Description', 'uicore-elements' ),
487 'type' => Controls_Manager::SWITCHER,
488 'label_on' => esc_html__( 'Show', 'uicore-elements' ),
489 'label_off' => esc_html__( 'Hide', 'uicore-elements' ),
490 'description' => esc_html__('Show descriptions only for active items.', 'uicore-elements'),
491 'return_value' => 'yes',
492 ]
493 );
494
495 $this->end_controls_section();
496
497 $this->start_controls_section(
498 'section_tabs_style',
499 [
500 'label' => esc_html__( 'Tabs', 'uicore-elements' ),
501 'tab' => Controls_Manager::TAB_STYLE,
502 ]
503 );
504
505 $this->add_responsive_control( 'tabs_title_space_between', [
506 'label' => esc_html__( 'Gap between tabs', 'uicore-elements' ),
507 'type' => Controls_Manager::SLIDER,
508 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
509 'range' => [
510 'px' => [
511 'max' => 100,
512 ],
513 'em' => [
514 'max' => 40,
515 ],
516 'rem' => [
517 'max' => 40,
518 ],
519 ],
520 'default' => [
521 'size' => 10,
522 'unit' => 'px',
523 ],
524 'selectors' => [
525 '{{WRAPPER}}' => '--ui-e-tabs-title-gap: {{SIZE}}{{UNIT}}',
526 ],
527 ] );
528
529 $this->add_responsive_control( 'tabs_title_spacing', [
530 'label' => esc_html__( 'Distance from content', 'uicore-elements' ),
531 'type' => Controls_Manager::SLIDER,
532 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
533 'range' => [
534 'px' => [
535 'max' => 100,
536 ],
537 'em' => [
538 'max' => 40,
539 ],
540 'rem' => [
541 'max' => 40,
542 ],
543 ],
544 'selectors' => [
545 '{{WRAPPER}}' => '--ui-e-tabs-gap: {{SIZE}}{{UNIT}}',
546 ],
547 ] );
548
549 $this->start_controls_tabs( 'tabs_title_style' );
550
551 $this->start_controls_tab(
552 'tabs_title_normal',
553 [
554 'label' => esc_html__( 'Normal', 'uicore-elements' ),
555 ]
556 );
557
558 $this->add_group_control(
559 Group_Control_Background::get_type(),
560 [
561 'name' => 'tabs_title_background_color',
562 'types' => [ 'classic', 'gradient' ],
563 'exclude' => [ 'image' ],
564 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]",
565 'fields_options' => [
566 'color' => [
567 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
568 'selectors' => [
569 '{{SELECTOR}}' => 'background: {{VALUE}}',
570 ],
571 ],
572 ],
573 ]
574 );
575
576 $this->add_group_control(
577 Group_Control_Border::get_type(),
578 [
579 'name' => 'tabs_title_border',
580 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]",
581 'fields_options' => [
582 'color' => [
583 'label' => esc_html__( 'Border Color', 'uicore-elements' ),
584 ],
585 'width' => [
586 'label' => esc_html__( 'Border Width', 'uicore-elements' ),
587 ],
588 ],
589 ]
590 );
591
592 $this->add_group_control(
593 Group_Control_Box_Shadow::get_type(),
594 [
595 'name' => 'tabs_title_box_shadow',
596 'label' => esc_html__( 'Shadow', 'uicore-elements' ),
597 'separator' => 'after',
598 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]",
599 ]
600 );
601
602 $this->end_controls_tab();
603
604 $this->start_controls_tab(
605 'tabs_title_hover',
606 [
607 'label' => esc_html__( 'Hover', 'uicore-elements' ),
608 ]
609 );
610
611 $this->add_group_control(
612 Group_Control_Background::get_type(),
613 [
614 'name' => 'tabs_title_background_color_hover',
615 'types' => [ 'classic', 'gradient' ],
616 'exclude' => [ 'image' ],
617 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover",
618 'fields_options' => [
619 'background' => [
620 'default' => 'classic',
621 ],
622 'color' => [
623 'global' => [
624 'default' => Global_Colors::COLOR_ACCENT,
625 ],
626 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
627 'selectors' => [
628 '{{SELECTOR}}' => 'background: {{VALUE}};',
629 ],
630 ],
631 ],
632 ]
633 );
634
635 $this->add_group_control(
636 Group_Control_Border::get_type(),
637 [
638 'name' => 'tabs_title_border_hover',
639 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover",
640 'fields_options' => [
641 'color' => [
642 'label' => esc_html__( 'Border Color', 'uicore-elements' ),
643 ],
644 'width' => [
645 'label' => esc_html__( 'Border Width', 'uicore-elements' ),
646 ],
647 ],
648 ]
649 );
650
651 $this->add_group_control(
652 Group_Control_Box_Shadow::get_type(),
653 [
654 'name' => 'tabs_title_box_shadow_hover',
655 'label' => esc_html__( 'Shadow', 'uicore-elements' ),
656 'separator' => 'after',
657 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover",
658 ]
659 );
660
661 $this->add_control(
662 'hover_animation',
663 [
664 'label' => esc_html__( 'Hover Animation', 'uicore-elements' ),
665 'type' => Controls_Manager::HOVER_ANIMATION,
666 ]
667 );
668
669 $this->add_control(
670 'tabs_title_transition_duration',
671 [
672 'label' => esc_html__( 'Transition Duration', 'uicore-elements' ) . ' (s)',
673 'type' => Controls_Manager::SLIDER,
674 'selectors' => [
675 '{{WRAPPER}}' => '--ui-e-tabs-title-transition: {{SIZE}}s',
676 ],
677 'range' => [
678 'px' => [
679 'min' => 0,
680 'max' => 3,
681 'step' => 0.1,
682 ],
683 ],
684 ]
685 );
686
687 $this->end_controls_tab();
688
689 $this->start_controls_tab(
690 'tabs_title_active',
691 [
692 'label' => esc_html__( 'Active', 'uicore-elements' ),
693 ]
694 );
695
696 $this->add_group_control(
697 Group_Control_Background::get_type(),
698 [
699 'name' => 'tabs_title_background_color_active',
700 'types' => [ 'classic', 'gradient' ],
701 'exclude' => [ 'image' ],
702 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"]",
703 'fields_options' => [
704 'background' => [
705 'default' => 'classic',
706 ],
707 'color' => [
708 'global' => [
709 'default' => Global_Colors::COLOR_ACCENT,
710 ],
711 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
712 'selectors' => [
713 '{{SELECTOR}}' => 'background: {{VALUE}};',
714 ],
715 ],
716 ],
717 ]
718 );
719
720 $this->add_group_control(
721 Group_Control_Border::get_type(),
722 [
723 'name' => 'tabs_title_border_active',
724 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"]",
725 'fields_options' => [
726 'color' => [
727 'label' => esc_html__( 'Border Color', 'uicore-elements' ),
728 ],
729 'width' => [
730 'label' => esc_html__( 'Border Width', 'uicore-elements' ),
731 ],
732 ],
733 ]
734 );
735
736 $this->add_group_control(
737 Group_Control_Box_Shadow::get_type(),
738 [
739 'name' => 'tabs_title_box_shadow_active',
740 'label' => esc_html__( 'Shadow', 'uicore-elements' ),
741 'selector' => "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"]",
742 ]
743 );
744
745 $this->end_controls_tab();
746
747 $this->end_controls_tabs();
748
749 $this->add_control(
750 'tabs_pill',
751 [
752 'label' => esc_html__( 'Pill Style', 'uicore-elements' ),
753 'type' => Controls_Manager::SWITCHER,
754 'return_value' => 'yes',
755 'prefix_class' => 'ui-e-pill-tabs-',
756 'separator' => 'before',
757 'device_args' => [
758 'desktop' => [
759 'condition' => [
760 'tabs_direction' => ['block-start', 'block-end'],
761 ],
762 ],
763 'mobile' => [
764 'condition' => [
765 'tabs_direction' => ['block-start', 'block-end'],
766 ]
767 ],
768 'tablet' => [
769 'condition' => [
770 'tabs_direction' => ['block-start', 'block-end'],
771 ]
772 ]
773 ],
774 ]
775 );
776
777 $this->add_responsive_control(
778 'tabs_title_border_radius',
779 [
780 'label' => esc_html__( 'Border Radius', 'uicore-elements' ),
781 'type' => Controls_Manager::DIMENSIONS,
782 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
783 'selectors' => [
784 "{$heading_selector}" => '--ui-e-tab-border-top: {{TOP}}{{UNIT}}; --ui-e-tab-border-right: {{RIGHT}}{{UNIT}}; --ui-e-tab-border-bot: {{BOTTOM}}{{UNIT}}; --ui-e-tab-border-left: {{LEFT}}{{UNIT}};',
785 ],
786 ]
787 );
788
789 $this->add_responsive_control(
790 'padding',
791 [
792 'label' => esc_html__( 'Padding', 'uicore-elements' ),
793 'type' => Controls_Manager::DIMENSIONS,
794 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
795 'selectors' => [
796 "{$heading_selector} > .ui-e-tab-title" => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
797 ],
798 ]
799 );
800
801 $this->end_controls_section();
802
803 $this->start_controls_section(
804 'section_title_style',
805 [
806 'label' => esc_html__( 'Titles', 'uicore-elements' ),
807 'tab' => Controls_Manager::TAB_STYLE,
808 ]
809 );
810
811 $this->add_group_control( Group_Control_Typography::get_type(), [
812 'name' => 'title_typography',
813 'global' => [
814 'default' => Global_Typography::TYPOGRAPHY_ACCENT,
815 ],
816 'selector' => "{$heading_selector} .ui-e-tab-texts span",
817 ] );
818
819 $this->start_controls_tabs( 'title_style' );
820
821 $this->start_controls_tab(
822 'title_normal',
823 [
824 'label' => esc_html__( 'Normal', 'uicore-elements' ),
825 ]
826 );
827
828 $this->add_control(
829 'title_text_color',
830 [
831 'label' => esc_html__( 'Color', 'uicore-elements' ),
832 'type' => Controls_Manager::COLOR,
833 'selectors' => [
834 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"] .ui-e-tab-texts > span" => 'color: {{VALUE}}',
835 ],
836 ]
837 );
838
839 $this->end_controls_tab();
840
841 $this->start_controls_tab(
842 'title_hover',
843 [
844 'label' => esc_html__( 'Hover', 'uicore-elements' ),
845 ]
846 );
847
848 $this->add_control(
849 'title_text_color_hover',
850 [
851 'label' => esc_html__( 'Color', 'uicore-elements' ),
852 'type' => Controls_Manager::COLOR,
853 'selectors' => [
854 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover .ui-e-tab-texts > span" => 'color: {{VALUE}}',
855 ],
856 ]
857 );
858
859 $this->end_controls_tab();
860
861 $this->start_controls_tab(
862 'title_active',
863 [
864 'label' => esc_html__( 'Active', 'uicore-elements' ),
865 ]
866 );
867
868 $this->add_control(
869 'title_text_color_active',
870 [
871 'label' => esc_html__( 'Color', 'uicore-elements' ),
872 'type' => Controls_Manager::COLOR,
873 'selectors' => [
874 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"] .ui-e-tab-texts > span" => 'color: {{VALUE}}',
875 ],
876 ]
877 );
878
879 $this->end_controls_tab();
880
881 $this->end_controls_tabs();
882
883 $this->end_controls_section();
884
885 $this->start_controls_section(
886 'section_description_style',
887 [
888 'label' => esc_html__( 'Description', 'uicore-elements' ),
889 'tab' => Controls_Manager::TAB_STYLE,
890 ]
891 );
892
893 $this->add_group_control( Group_Control_Typography::get_type(), [
894 'name' => 'description_typography',
895 'global' => [
896 'default' => Global_Typography::TYPOGRAPHY_ACCENT,
897 ],
898 'selector' => "{$heading_selector} .ui-e-tab-texts p",
899 ] );
900
901 $this->add_responsive_control(
902 'description_spacing',
903 [
904 'label' => esc_html__( 'Top Spacing', 'uicore-elements' ),
905 'type' => Controls_Manager::SLIDER,
906 'range' => [
907 'px' => [
908 'max' => 50,
909 ],
910 '%' => [
911 'max' => 50,
912 'step' => 0.1,
913 ],
914 ],
915 'default' => [
916 'size' => 0,
917 'unit' => 'px',
918 ],
919 'size_units' => [ 'px', 'em', 'rem', '%'],
920 'selectors' => [
921 "{$heading_selector} .ui-e-tab-texts > p" => 'margin-top: {{SIZE}}{{UNIT}}',
922 ],
923 ]
924 );
925
926 $this->start_controls_tabs( 'description_style' );
927
928 $this->start_controls_tab(
929 'description_normal',
930 [
931 'label' => esc_html__( 'Normal', 'uicore-elements' ),
932 ]
933 );
934
935 $this->add_control(
936 'description_text_color',
937 [
938 'label' => esc_html__( 'Color', 'uicore-elements' ),
939 'type' => Controls_Manager::COLOR,
940 'selectors' => [
941 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"] .ui-e-tab-texts > p" => 'color: {{VALUE}}',
942 ],
943 ]
944 );
945
946 $this->end_controls_tab();
947
948 $this->start_controls_tab(
949 'description_hover',
950 [
951 'label' => esc_html__( 'Hover', 'uicore-elements' ),
952 ]
953 );
954
955 $this->add_control(
956 'description_text_color_hover',
957 [
958 'label' => esc_html__( 'Color', 'uicore-elements' ),
959 'type' => Controls_Manager::COLOR,
960 'selectors' => [
961 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"false\"]:hover .ui-e-tab-texts > p" => 'color: {{VALUE}}',
962 ],
963 ]
964 );
965
966 $this->end_controls_tab();
967
968 $this->start_controls_tab(
969 'description_active',
970 [
971 'label' => esc_html__( 'Active', 'uicore-elements' ),
972 ]
973 );
974
975 $this->add_control(
976 'description_text_color_active',
977 [
978 'label' => esc_html__( 'Color', 'uicore-elements' ),
979 'type' => Controls_Manager::COLOR,
980 'selectors' => [
981 "{$heading_selector} > .ui-e-tab-title[aria-selected=\"true\"] .ui-e-tab-texts > p" => 'color: {{VALUE}}',
982 ],
983 ]
984 );
985
986 $this->end_controls_tab();
987
988 $this->end_controls_tabs();
989
990 $this->end_controls_section();
991
992 $this->start_controls_section(
993 'icon_section_style',
994 [
995 'label' => esc_html__( 'Icon', 'uicore-elements' ),
996 'tab' => Controls_Manager::TAB_STYLE,
997 ]
998 );
999
1000 $this->add_responsive_control( 'icon_size', [
1001 'label' => esc_html__( 'Size', 'uicore-elements' ),
1002 'type' => Controls_Manager::SLIDER,
1003 'range' => [
1004 'px' => [
1005 'max' => 100,
1006 ],
1007 'em' => [
1008 'max' => 10,
1009 ],
1010 'rem' => [
1011 'max' => 10,
1012 ],
1013 ],
1014 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ],
1015 'selectors' => [
1016 '{{WRAPPER}}' => '--ui-e-tabs-icon-size: {{SIZE}}{{UNIT}}',
1017 ],
1018 ] );
1019
1020 $this->add_responsive_control( 'icon_spacing', [
1021 'label' => esc_html__( 'Spacing', 'uicore-elements' ),
1022 'type' => Controls_Manager::SLIDER,
1023 'range' => [
1024 'px' => [
1025 'max' => 200,
1026 ],
1027 'vw' => [
1028 'max' => 50,
1029 'step' => 0.1,
1030 ],
1031 ],
1032 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ],
1033 'selectors' => [
1034 '{{WRAPPER}} .ui-e-tab-title' => 'gap: {{SIZE}}{{UNIT}}',
1035 ],
1036 ] );
1037
1038 $this->add_control(
1039 'icon_padding',
1040 [
1041 'label' => esc_html__( 'Padding', 'uicore-elements' ),
1042 'type' => Controls_Manager::DIMENSIONS,
1043 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
1044 'selectors' => [
1045 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1046 ],
1047 ]
1048 );
1049
1050 $this->add_control(
1051 'icon_border_radius',
1052 [
1053 'label' => esc_html__( 'Border Radius', 'uicore-elements' ),
1054 'type' => Controls_Manager::DIMENSIONS,
1055 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
1056 'selectors' => [
1057 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1058 ],
1059 ]
1060 );
1061
1062 $this->add_group_control(
1063 Group_Control_Border::get_type(),
1064 [
1065 'name' => 'icon_border',
1066 'selector' => '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon',
1067 ]
1068 );
1069
1070 $this->start_controls_tabs( 'icon_style_states' );
1071
1072 $this->start_controls_tab(
1073 'icon_section_normal',
1074 [
1075 'label' => esc_html__( 'Normal', 'uicore-elements' ),
1076 ]
1077 );
1078
1079 $this->add_control( 'icon_color', [
1080 'label' => esc_html__( 'Color', 'uicore-elements' ),
1081 'type' => Controls_Manager::COLOR,
1082 'selectors' => [
1083 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon > i' => 'color: {{VALUE}}',
1084 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon > svg' => 'fill: {{VALUE}}',
1085 ],
1086 ] );
1087
1088 $this->add_control(
1089 'icon_background_color',
1090 [
1091 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
1092 'type' => Controls_Manager::COLOR,
1093 'selectors' => [
1094 '{{WRAPPER}} .ui-e-tab-title .ui-e-tab-icon' => 'background-color: {{VALUE}}',
1095 ],
1096 ]
1097 );
1098
1099 $this->end_controls_tab();
1100
1101 $this->start_controls_tab(
1102 'icon_section_hover',
1103 [
1104 'label' => esc_html__( 'Hover', 'uicore-elements' ),
1105 ]
1106 );
1107
1108 $this->add_control( 'icon_color_hover', [
1109 'label' => esc_html__( 'Color', 'uicore-elements' ),
1110 'type' => Controls_Manager::COLOR,
1111 'selectors' => [
1112 '{{WRAPPER}} .ui-e-tab-title:hover .ui-e-tab-icon > i' => 'color: {{VALUE}}',
1113 '{{WRAPPER}} .ui-e-tab-title:hover .ui-e-tab-icon > svg' => 'fill: {{VALUE}}',
1114 ],
1115 ] );
1116
1117 $this->add_control(
1118 'icon_background_color_hover',
1119 [
1120 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
1121 'type' => Controls_Manager::COLOR,
1122 'selectors' => [
1123 '{{WRAPPER}} .ui-e-tab-title:hover .ui-e-tab-icon' => 'background-color: {{VALUE}}',
1124 ],
1125 ]
1126 );
1127
1128 $this->end_controls_tab();
1129
1130 $this->start_controls_tab(
1131 'icon_section_active',
1132 [
1133 'label' => esc_html__( 'Active', 'uicore-elements' ),
1134 ]
1135 );
1136
1137 $this->add_control( 'icon_color_active', [
1138 'label' => esc_html__( 'Color', 'uicore-elements' ),
1139 'type' => Controls_Manager::COLOR,
1140 'selectors' => [
1141 '{{WRAPPER}} .ui-e-tab-title[aria-selected="true"] .ui-e-tab-icon > i' => 'color: {{VALUE}}',
1142 '{{WRAPPER}} .ui-e-tab-title[aria-selected="true"] .ui-e-tab-icon > svg' => 'fill: {{VALUE}}',
1143 ],
1144 ] );
1145
1146 $this->add_control(
1147 'icon_background_color_active',
1148 [
1149 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
1150 'type' => Controls_Manager::COLOR,
1151 'selectors' => [
1152 '{{WRAPPER}} .ui-e-tab-title[aria-selected="true"] .ui-e-tab-icon' => 'background-color: {{VALUE}}',
1153 ],
1154 ]
1155 );
1156
1157 $this->end_controls_tab();
1158
1159 $this->end_controls_tabs();
1160
1161 $this->end_controls_section();
1162
1163 $this->start_controls_section( 'section_box_style', [
1164 'label' => esc_html__( 'Content', 'uicore-elements' ),
1165 'tab' => Controls_Manager::TAB_STYLE,
1166 ] );
1167
1168 $this->add_group_control(
1169 Group_Control_Background::get_type(),
1170 [
1171 'name' => 'box_background_color',
1172 'types' => [ 'classic', 'gradient' ],
1173 'exclude' => [ 'image' ],
1174 'selector' => $content_selector,
1175 'fields_options' => [
1176 'color' => [
1177 'label' => esc_html__( 'Background Color', 'uicore-elements' ),
1178 ],
1179 ],
1180 ]
1181 );
1182
1183 $this->add_group_control(
1184 Group_Control_Border::get_type(),
1185 [
1186 'name' => 'box_border',
1187 'selector' => $content_selector,
1188 'fields_options' => [
1189 'color' => [
1190 'label' => esc_html__( 'Border Color', 'uicore-elements' ),
1191 ],
1192 'width' => [
1193 'label' => esc_html__( 'Border Width', 'uicore-elements' ),
1194 ],
1195 ],
1196 ]
1197 );
1198
1199 $this->add_responsive_control(
1200 'box_border_radius',
1201 [
1202 'label' => esc_html__( 'Border Radius', 'uicore-elements' ),
1203 'type' => Controls_Manager::DIMENSIONS,
1204 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
1205 'selectors' => [
1206 $content_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1207 ],
1208 ]
1209 );
1210
1211 $this->add_group_control(
1212 Group_Control_Box_Shadow::get_type(),
1213 [
1214 'name' => 'box_shadow_box_shadow',
1215 'selector' => $content_selector,
1216 ]
1217 );
1218
1219 $this->add_responsive_control(
1220 'box_padding',
1221 [
1222 'label' => esc_html__( 'Padding', 'uicore-elements' ),
1223 'type' => Controls_Manager::DIMENSIONS,
1224 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
1225 'selectors' => [
1226 $content_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1227 ],
1228 ]
1229 );
1230
1231 $this->end_controls_section();
1232
1233 }
1234
1235 protected function maybe_render_tab_icons_html( $item_settings ): void {
1236 $icon_settings = $item_settings['item']['tab_icon'];
1237
1238 if ( empty( $icon_settings['value'] ) ) {
1239 return;
1240 }
1241
1242 $active_icon_settings = $this->is_active_icon_exist( $item_settings['item'] )
1243 ? $item_settings['item']['tab_icon_active']
1244 : $icon_settings;
1245 ?>
1246 <span <?php $this->print_render_attribute_string( 'tab-icon' ); ?>>
1247 <?php Icons_Manager::render_icon( $active_icon_settings, [ 'aria-hidden' => 'true' ] ); ?>
1248 <?php Icons_Manager::render_icon( $icon_settings, [ 'aria-hidden' => 'true' ] ); ?>
1249 </span>
1250 <?php
1251 }
1252
1253 protected function render_tab_titles_html( $item_settings ): string {
1254 // Data
1255 $setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $item_settings['index'] );
1256 $title = $item_settings['item']['tab_title'];
1257 $description = $item_settings['item']['tab_description'];
1258 // Classes
1259 $hover_animation = $item_settings['hover_animation'] ? 'elementor-animation-' . $item_settings['hover_animation'] : '';
1260 $toggle_description = $item_settings['show_description'] ? 'ui-e-toggle-description' : '';
1261
1262 $this->add_render_attribute( $setting_key, [
1263 'id' => $item_settings['tab_id'],
1264 'class' => [
1265 'ui-e-tab-title',
1266 $toggle_description,
1267 $hover_animation
1268 ],
1269 'aria-selected' => (1 === (int)$item_settings['tab_count'] ? 'true' : 'false'),
1270 'data-tab-index' => $item_settings['tab_count'],
1271 'role' => 'tab',
1272 'tabindex' => (1 === $item_settings['tab_count'] ? '0' : '-1'),
1273 'aria-controls' => $item_settings['container_id'],
1274 'style' => '--ui-e-tabs-order: ' . $item_settings['tab_count'] . ';',
1275 ] );
1276
1277 $render_attributes = $this->get_render_attribute_string( $setting_key );
1278 $text_class = $this->get_render_attribute_string( 'tab-texts' );
1279
1280 ob_start();
1281 ?>
1282 <button <?php echo $render_attributes; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1283 <?php $this->maybe_render_tab_icons_html( $item_settings ); ?>
1284 <div <?php echo $text_class; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1285
1286 <?php if( !empty( $title ) ) : ?>
1287 <span> <?php echo wp_kses_post( $title ); ?> </span>
1288 <?php endif; ?>
1289
1290 <?php if( !empty( $description ) ) : ?>
1291 <p> <?php echo wp_kses_post( $description ); ?> </p>
1292 <?php endif; ?>
1293
1294 </div>
1295 </button>
1296 <?php
1297 return ob_get_clean();
1298 }
1299
1300 protected function render_tab_containers_html( $item_settings ): string {
1301 ob_start();
1302 $this->print_child( $item_settings['index'], $item_settings );
1303 return ob_get_clean();
1304 }
1305
1306 private function is_active_icon_exist( $item ) {
1307 return array_key_exists( 'tab_icon_active', $item ) && ! empty( $item['tab_icon_active'] ) && ! empty( $item['tab_icon_active']['value'] );
1308 }
1309
1310 /**
1311 * Print the content area.
1312 *
1313 * @param int $index
1314 * @param array $item_settings
1315 */
1316 public function print_child( $index, $item_settings = [] ) {
1317 $children = $this->get_children();
1318 $child_ids = [];
1319 if( empty( $children )){
1320 return;
1321 }
1322 foreach ( $children as $child ) {
1323 $child_ids[] = $child->get_id();
1324 }
1325
1326 // Add data-tab-index attribute to the content area.
1327 $add_attribute_to_container = function ( $should_render, $container ) use ( $item_settings, $child_ids ) {
1328 if ( in_array( $container->get_id(), $child_ids ) ) {
1329 $this->add_attributes_to_container( $container, $item_settings );
1330 }
1331
1332 return $should_render;
1333 };
1334
1335 add_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container, 10, 3 );
1336 $children[ $index ]->print_element();
1337 remove_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container );
1338 }
1339
1340 protected function add_attributes_to_container( $container, $item_settings ) {
1341 $container->add_render_attribute( '_wrapper', [
1342 'id' => $item_settings['container_id'],
1343 'role' => 'tabpanel',
1344 'aria-labelledby' => $item_settings['tab_id'],
1345 'data-tab-index' => $item_settings['tab_count'],
1346 'style' => '--ui-e-tabs-order: ' . $item_settings['tab_count'] . ';',
1347 'class' => 0 === $item_settings['index'] ? 'e-active' : '',
1348 ] );
1349 }
1350
1351 protected function render() {
1352
1353 if( Plugin::$instance->experiments->is_feature_active('nested-elements') == false ){
1354 $this->nesting_fallback();
1355 return;
1356 }
1357
1358 $settings = $this->get_settings_for_display();
1359 $widget_number = substr( $this->get_id_int(), 0, 3 );
1360
1361 $this->add_render_attribute( 'elementor-tabs', [
1362 'class' => 'ui-e-tabs',
1363 'data-widget-number' => $widget_number,
1364 'aria-label' => esc_html__( 'Tabs. Open items with Enter or Space, close with Escape and navigate using the Arrow keys.', 'uicore-elements' ),
1365 ] );
1366
1367 $this->add_render_attribute( 'tab-texts', 'class', 'ui-e-tab-texts' );
1368 $this->add_render_attribute( 'tab-icon', 'class', 'ui-e-tab-icon' );
1369 $this->add_render_attribute( 'tab-icon-active', 'class', [ 'ui-e-tab-icon' ] );
1370
1371 $tab_titles_html = '';
1372 $tab_containers_html = '';
1373
1374 foreach ( $settings['tabs'] as $index => $item ) {
1375 $tab_count = $index + 1;
1376
1377 $tab_id = empty( $item['tab_id'] )
1378 ? 'ui-e-tab-title-' . $widget_number . $tab_count
1379 : $item['tab_id'];
1380
1381 $item_settings = [
1382 'index' => $index,
1383 'tab_count' => $tab_count,
1384 'tab_id' => $tab_id,
1385 'container_id' => 'ui-e-tab-content-' . $widget_number . $tab_count,
1386 'widget_number' => $widget_number,
1387 'hover_animation' => $settings['hover_animation'],
1388 'show_description' => $settings['show_description'],
1389 'item' => $item,
1390 'settings' => $settings,
1391 ];
1392
1393 $tab_titles_html .= $this->render_tab_titles_html( $item_settings );
1394 $tab_containers_html .= $this->render_tab_containers_html( $item_settings );
1395 }
1396 ?>
1397 <div <?php $this->print_render_attribute_string( 'elementor-tabs' ); ?>>
1398 <div class="ui-e-tabs-heading" role="tablist">
1399 <?php echo $tab_titles_html;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1400 </div>
1401 <div class="ui-e-tabs-content">
1402 <?php echo $tab_containers_html;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1403 </div>
1404 </div>
1405 <?php
1406 }
1407
1408 protected function get_initial_config(): array {
1409 if ( Plugin::$instance->experiments->is_feature_active( 'e_nested_atomic_repeaters' ) ) {
1410 return array_merge( parent::get_initial_config(), [
1411 'support_improved_repeaters' => true,
1412 'target_container' => [ '.ui-e-tabs-heading' ],
1413 'node' => 'button',
1414 ] );
1415 }
1416
1417 return parent::get_initial_config();
1418 }
1419 /*
1420 protected function content_template_single_repeater_item() {
1421 ?>
1422 <#
1423 const tabCount = view.collection.length + 1,
1424 elementUid = view.getIDInt().toString().substring( 0, 3 ) + tabCount,
1425 tabIcon = elementor.helpers.renderIcon( view, data.tab_icon, { 'aria-hidden': true }, 'i' , 'object' );
1426
1427 let tabActiveIcon = tabIcon,
1428 tabId = 'ui-e-tab-title-' + elementUid;
1429
1430 if ( '' !== data.tab_icon_active.value ) {
1431 tabActiveIcon = elementor.helpers.renderIcon( view, data.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' );
1432 }
1433
1434 const tabWrapperKey = {
1435 'id': 'ui-e-tab-title-' + elementUid,
1436 'class': [ 'ui-e-tab-title' ],
1437 'data-tab-index': tabCount,
1438 'role': 'tab',
1439 'aria-selected': 1 === tabCount ? 'true' : 'false',
1440 'tabindex': 1 === tabCount ? '0' : '-1',
1441 'aria-controls': 'ui-e-tab-content-' + elementUid,
1442 'style': '--ui-e-tabs-order: ' + tabCount + ';',
1443 };
1444
1445 const tabIconKey = {
1446 'class': [ 'ui-e-tab-icon' ],
1447 'data-binding-type': 'repeater-item',
1448 'data-binding-repeater-name': 'tabs',
1449 'data-binding-setting': [ data.tab_icon.value, data.tab_icon_active.value ],
1450 'data-binding-index': tabCount,
1451 };
1452
1453 const tabTitleKey = {
1454 'class': [ 'ui-e-tab-title-text' ],
1455 'data-binding-type': 'repeater-item',
1456 'data-binding-repeater-name': 'tabs',
1457 'data-binding-setting': [ 'tab_title' ],
1458 'data-binding-index': tabCount,
1459 };
1460
1461 view.addRenderAttribute( 'button-container', tabWrapperKey, null, true );
1462 view.addRenderAttribute( 'tab-title-container', tabTitleKey, null, true );
1463 view.addRenderAttribute( 'tab-icon-key-container', tabIconKey, null, true );
1464 #>
1465
1466 <button {{{ view.getRenderAttributeString( 'button-container' ) }}}>
1467 <# if ( tabIcon.value ) { #>
1468 <span {{{ view.getRenderAttributeString( 'tab-icon-key-container' ) }}}> {{{ tabIcon.value }}}{{{ tabActiveIcon.value }}} </span>
1469 <# } #>
1470 <span {{{ view.getRenderAttributeString( 'tab-title-container' ) }}}> {{{ data.tab_title }}} </span>
1471 </button>
1472 <?php
1473 }
1474 */
1475 /*
1476 protected function content_template_single_repeater_item() {
1477 ?>
1478 <#
1479 const tabIndex = view.collection.length,
1480 elementUid = view.getIDInt().toString(),
1481 item = data,
1482 hoverAnimationSetting = view?.container?.settings?.attributes?.hover_animation;
1483 hoverAnimationClass = hoverAnimationSetting
1484 ? `elementor-animation-${ hoverAnimationSetting }`
1485 : '';
1486 #>
1487 <?php $this->content_template_single_item( '{{ tabIndex }}', '{{ item }}', '{{ elementUid }}', '{{ hoverAnimationClass }}' );
1488 }
1489 */
1490 protected function content_template() {
1491
1492 if( Plugin::$instance->experiments->is_feature_active('nested-elements') == false ){
1493 return;
1494 }
1495
1496 ?>
1497 <# const elementUid = view.getIDInt().toString().substr( 0, 3 ); #>
1498 <div class="ui-e-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.', 'uicore-elements' ); ?>">
1499 <# if ( settings['tabs'] ) { #>
1500 <div class="ui-e-tabs-heading" role="tablist">
1501 <# _.each( settings['tabs'], function( item, index ) {
1502 const tabCount = index + 1,
1503 tabUid = elementUid + tabCount,
1504 tabWrapperKey = tabUid,
1505 tabTitleKey = 'tab-title-' + tabUid,
1506 tabIconKey = 'tab-icon-' + tabUid,
1507 tabIcon = elementor.helpers.renderIcon( view, item.tab_icon, { 'aria-hidden': true }, 'i' , 'object' ),
1508 hoverAnimationClass = settings['hover_animation'] ? `elementor-animation-${ settings['hover_animation'] }` : '',
1509 showDescription = settings['show_description'] ? 'ui-e-toggle-description' : '';
1510
1511 let tabActiveIcon = tabIcon,
1512 tabId = 'ui-e-tab-title-' + tabUid;
1513
1514 if ( '' !== item.tab_icon_active.value ) {
1515 tabActiveIcon = elementor.helpers.renderIcon( view, item.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' );
1516 }
1517
1518 if ( '' !== item.tab_id ) {
1519 tabId = item.tab_id;
1520 }
1521
1522 view.addRenderAttribute( tabWrapperKey, {
1523 'id': tabId,
1524 'class': [ 'ui-e-tab-title', hoverAnimationClass, showDescription ],
1525 'data-tab-index': tabCount,
1526 'role': 'tab',
1527 'aria-selected': 1 === tabCount ? 'true' : 'false',
1528 'tabindex': 1 === tabCount ? '0' : '-1',
1529 'aria-controls': 'ui-e-tab-content-' + tabUid,
1530 'style': '--ui-e-tabs-order: ' + tabCount + ';',
1531 } );
1532
1533 view.addRenderAttribute( tabTitleKey, {
1534 'class': [ 'ui-e-tab-texts' ],
1535 'data-binding-type': 'repeater-item',
1536 'data-binding-repeater-name': 'tabs',
1537 'data-binding-setting': [ 'tab_title' ],
1538 'data-binding-index': tabCount,
1539 } );
1540
1541 view.addRenderAttribute( tabIconKey, {
1542 'class': [ 'ui-e-tab-icon' ],
1543 'data-binding-type': 'repeater-item',
1544 'data-binding-repeater-name': 'tabs',
1545 'data-binding-setting': [ 'tab_icon.value', 'tab_icon_active.value' ],
1546 'data-binding-index': tabCount,
1547 } );
1548 #>
1549 <button {{{ view.getRenderAttributeString( tabWrapperKey ) }}}>
1550 <# if ( tabIcon.value ) { #>
1551 <span {{{ view.getRenderAttributeString( tabIconKey ) }}}>{{{ tabActiveIcon.value }}}{{{ tabIcon.value }}}</span>
1552 <# } #>
1553 <div {{{ view.getRenderAttributeString( tabTitleKey ) }}}>
1554 <# if ( item.tab_title ) { #>
1555 <span> {{{ item.tab_title }}} </span>
1556 <# } #>
1557 <# if ( item.tab_description ) { #>
1558 <p> {{{ item.tab_description }}} </p>
1559 <# } #>
1560 </div>
1561 </button>
1562 <# } ); #>
1563 </div>
1564 <div class="ui-e-tabs-content"></div>
1565 <# } #>
1566 </div>
1567 <?php
1568 }
1569 /*
1570 private function content_template_single_item( $tab_index, $item, $element_uid, $hover_animation_class ) {
1571 ?>
1572 <#
1573 const tabCount = tabIndex + 1,
1574 tabId = item.tab_id
1575 ? item.tab_id
1576 : 'ui-e-tab-title-' + elementUid + ( tabIndex + 1 ),
1577 tabUid = elementUid + tabCount,
1578 tabIcon = elementor.helpers.renderIcon( view, item.tab_icon, { 'aria-hidden': true }, 'i' , 'object' ),
1579 activeTabIcon = item.tab_icon_active.value
1580 ? elementor.helpers.renderIcon( view, item.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' )
1581 : tabIcon,
1582 escapedHoverAnimationClass = _.escape( hoverAnimationClass );
1583
1584 view.addRenderAttribute( 'tab-title', {
1585 'id': tabId,
1586 'class': [ 'ui-e-tab-title',escapedHoverAnimationClass ],
1587 'data-tab-index': tabCount,
1588 'role': 'tab',
1589 'aria-selected': 1 === tabCount ? 'true' : 'false',
1590 'tabindex': 1 === tabCount ? '0' : '-1',
1591 'aria-controls': 'ui-e-tab-content-' + tabUid,
1592 'style': '--ui-e-tabs-order: ' + tabCount + ';',
1593 }, null, true );
1594
1595 view.addRenderAttribute( 'tab-title-text', {
1596 'class': [ 'ui-e-tab-title-text' ],
1597 'data-binding-type': 'repeater-item',
1598 'data-binding-repeater-name': 'tabs',
1599 'data-binding-setting': [ 'tab_title' ],
1600 'data-binding-index': tabCount,
1601 'data-binding-dynamic': 'true',
1602 }, null, true );
1603
1604 view.addRenderAttribute( 'tab-icon', {
1605 'class': [ 'ui-e-tab-icon' ],
1606 'data-binding-type': 'repeater-item',
1607 'data-binding-repeater-name': 'tabs',
1608 'data-binding-setting': [ 'tab_icon', 'tab_icon_active' ],
1609 'data-binding-index': tabCount,
1610 }, null, true );
1611 #>
1612
1613 <button {{{ view.getRenderAttributeString( 'tab-title' ) }}}>
1614 <# if ( !! item.tab_icon.value ) { #>
1615 <span {{{ view.getRenderAttributeString( 'tab-icon' ) }}}>{{{ tabIcon.value }}}{{{ activeTabIcon.value }}}</span>
1616 <# } #>
1617
1618 <span {{{ view.getRenderAttributeString( 'tab-title-text' ) }}}>{{{ item.tab_title }}}</span>
1619 </button>
1620 <?php
1621 }
1622 */
1623 }
1624 \Elementor\Plugin::instance()->widgets_manager->register(new Tabs());