PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.3.17
UiCore Elements – Free widgets and templates for Elementor v1.3.17
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.3.17, at includes/widgets/tabs.php

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