PluginProbe ʕ •ᴥ•ʔ
Elementor Website Builder – more than just a page builder / 4.0.0-dev3
Elementor Website Builder – more than just a page builder v4.0.0-dev3
4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.22.0-dev1 4.0.0-beta3 3.22.0-dev2 4.0.0-beta4 3.22.0-dev3 4.0.0-beta5 3.22.0-dev4 4.0.0-dev1 3.22.0-dev5 4.0.0-dev2 3.22.0-dev6 4.0.0-dev3 3.22.1 4.0.0-dev4 3.22.2 4.0.0-dev5 3.22.3 4.0.1 3.23.0 4.0.2 3.23.0-beta1 3.23.0-beta2 3.23.0-beta3 3.23.0-beta4 3.23.0-beta5 3.23.0-beta6 3.23.0-dev1 3.23.0-dev2 3.23.0-dev3 3.23.0-dev4 3.23.0-dev5 3.23.0-dev6 3.23.1 3.23.2 3.23.3 3.23.4 3.24.0 3.24.0-beta1 3.24.0-beta2 3.24.0-beta3 3.24.0-dev1 3.24.0-dev2 3.24.0-dev3 3.24.1 3.24.2 3.24.3 3.24.4 3.24.5 3.24.6 3.24.7 3.24.8 3.25.0 3.25.0-beta1 3.25.0-beta2 3.25.0-beta3 3.25.0-dev1 3.25.0-dev2 3.25.0-dev3 3.25.1 3.25.10 3.25.11 3.25.2 3.25.3 3.25.4 3.25.5 3.25.6 3.25.7 3.25.8 3.25.9 3.26.0 3.26.0-beta1 3.26.0-beta2 3.26.0-beta3 3.26.0-beta4 3.26.0-beta5 3.26.0-dev1 3.26.0-dev2 3.26.0-dev3 3.26.0-dev4 3.26.0-dev5 3.26.1 3.26.2 3.26.3 3.26.4 3.26.5 3.27.0 3.27.0-beta1 3.27.0-beta2 3.27.0-dev1 3.27.0-dev2 3.27.1 3.27.2 3.27.3 3.27.4 3.27.5 3.27.6 3.27.7 3.28.0 3.28.0-beta1 3.28.0-beta2 3.28.0-beta3 3.28.0-dev1 3.28.0-dev2 3.28.0-dev3 3.28.1 3.28.2 3.28.3 3.28.4 3.29.0 3.29.0-beta1 trunk 3.29.0-beta2 3.0.0 3.29.0-beta3 3.0.1 3.29.0-beta4 3.0.10 3.29.0-dev1 3.0.11 3.29.0-dev2 3.0.12 3.29.0-dev3 3.0.13 3.29.0-dev4 3.0.14 3.29.1 3.0.15 3.29.2 3.0.16 3.3.0 3.0.2 3.3.1 3.0.3 3.30.0 3.0.4 3.30.0-beta1 3.0.5 3.30.0-beta2 3.0.6 3.30.0-beta3 3.0.7 3.30.0-dev1 3.0.8 3.30.0-dev2 3.0.8.1 3.30.0-dev3 3.0.9 3.30.1 3.1.0 3.30.2 3.1.0-beta1 3.30.3 3.1.0-beta2 3.30.4 3.1.0-beta3 3.31.0 3.1.0-beta4 3.31.0-beta1 3.1.0-dev1 3.31.0-beta2 3.1.0-dev2 3.31.0-dev1 3.1.0-dev3 3.31.0-dev2 3.1.1 3.31.1 3.1.2 3.31.2 3.1.3 3.31.3 3.1.4 3.31.4 3.10.0 3.31.5 3.10.0-dev1 3.32.0 3.10.1 3.32.0-beta1 3.10.2 3.32.0-beta2 3.11.0 3.32.0-beta3 3.11.0-beta1 3.32.0-dev1 3.11.0-beta2 3.32.0-dev2 3.11.0-beta3 3.32.0-dev3 3.11.0-dev1 3.32.1 3.11.0-dev2 3.32.2 3.11.0-dev3 3.32.3 3.11.1 3.32.4 3.11.2 3.32.5 3.11.3 3.33.0 3.11.4 3.33.0-beta1 3.11.5 3.33.0-beta2 3.12.0 3.33.0-beta3 3.12.1 3.33.0-beta4 3.12.2 3.33.0-dev1 3.13.0 3.33.0-dev2 3.13.0-beta1 3.33.0-dev3 3.13.0-beta2 3.33.0-dev4 3.13.0-beta3 3.33.1 3.13.0-dev3 3.33.2 3.13.0-dev4 3.33.3 3.13.1 3.33.4 3.13.2 3.33.5 3.13.3 3.33.6 3.13.4 3.34.0 3.14.0 3.34.0-beta1 3.14.0-beta1 3.34.0-beta2 3.14.0-beta2 3.34.0-beta3 3.14.0-beta3 3.34.0-dev1 3.14.0-beta4 3.34.0-dev2 3.14.0-beta5 3.34.1 3.14.1 3.34.2 3.15.0 3.34.3 3.15.1 3.34.4 3.15.2 3.35.0 3.15.3 3.35.0-beta1 3.16.0 3.35.0-beta2 3.16.0-beta3 3.35.0-beta3 3.16.0-beta4 3.35.0-beta4 3.16.0-dev1 3.35.0-dev1 3.16.0-dev2 3.35.0-dev2 3.16.1 3.35.0-dev3 3.16.2 3.35.0-dev4 3.16.3 3.35.1 3.16.4 3.35.2 3.16.5 3.35.3 3.16.6 3.35.4 3.17.0 3.35.5 3.17.0-dev2 3.35.6 3.17.0-dev3 3.35.7 3.17.0-dev4 3.35.8 3.17.1 3.35.9 3.17.2 3.4.0 3.17.3 3.4.0-dev7 3.18.0 3.4.0-dev8 3.18.0-beta1 3.4.0-dev9 3.18.0-beta2 3.4.1 3.18.0-beta3 3.4.2 3.18.0-beta4 3.4.3 3.18.0-dev1 3.4.4 3.18.1 3.4.5 3.18.2 3.4.6 3.18.3 3.4.7 3.19.0 3.4.8 3.19.0-beta1 3.5.0 3.19.0-beta2 3.5.0-beta1 3.19.0-beta3 3.5.0-beta2 3.19.0-beta4 3.5.0-beta3 3.19.0-beta5 3.5.0-beta4 3.19.0-beta6 3.5.0-beta5 3.19.0-dev1 3.5.0-beta7 3.19.0-dev2 3.5.0-beta8 3.19.0-dev3 3.5.0-dev8 3.19.0-dev4 3.5.0-dev9 3.19.0-dev5 3.5.1 3.19.0-dev6 3.5.2 3.19.1 3.5.3 3.19.2 3.5.4 3.19.3 3.5.5 3.19.4 3.5.6 3.2.0 3.6.0 3.2.1 3.6.0-beta1 3.2.2 3.6.0-beta2 3.2.3 3.6.0-beta3 3.2.4 3.6.0-beta4 3.2.5 3.6.0-beta5 3.20.0 3.6.0-dev1 3.20.0-beta1 3.6.0-dev10 3.20.0-beta2 3.6.1 3.20.0-beta3 3.6.2 3.20.0-beta4 3.6.3 3.20.0-dev1 3.6.4 3.20.0-dev2 3.6.5 3.20.0-dev3 3.6.6 3.20.0-dev4 3.6.7 3.20.1 3.6.8 3.20.2 3.7.0 3.20.3 3.7.0-beta1 3.20.4 3.7.0-beta2 3.21.0 3.7.0-beta3 3.21.0-beta1 3.7.0-beta4 3.21.0-beta2 3.7.0-dev1 3.21.0-beta3 3.7.1 3.21.0-dev1 3.7.2 3.21.0-dev2 3.7.3 3.21.0-dev3 3.7.4 3.21.1 3.7.5 3.21.2 3.7.6 3.21.3 3.7.7 3.21.4 3.7.8 3.21.5 3.8.0 3.21.6 3.8.0-beta1 3.21.7 3.8.0-beta2 3.21.8 3.8.0-beta3 3.22.0 3.8.1 3.22.0-beta1 3.9.0 3.22.0-beta2 3.9.1 3.22.0-beta3 3.9.2 3.22.0-beta4 4.0.0 3.22.0-beta5 4.0.0-beta1 3.22.0-beta6 4.0.0-beta2
elementor / includes / widgets / tabs.php
elementor / includes / widgets Last commit date
traits 5 months ago accordion.php 9 months ago alert.php 9 months ago audio.php 1 year ago button.php 9 months ago common-base.php 8 months ago common-optimized.php 1 year ago common.php 1 year ago counter.php 5 months ago divider.php 7 months ago google-maps.php 1 year ago heading.php 4 months ago html.php 1 year ago icon-box.php 5 months ago icon-list.php 5 months ago icon.php 5 months ago image-box.php 5 months ago image-carousel.php 5 months ago image-gallery.php 5 months ago image.php 5 months ago inner-section.php 2 years ago menu-anchor.php 1 year ago progress.php 11 months ago rating.php 9 months ago read-more.php 1 year ago shortcode.php 1 year ago sidebar.php 1 year ago social-icons.php 2 months ago spacer.php 1 year ago star-rating.php 5 months ago tabs.php 5 months ago testimonial.php 5 months ago text-editor.php 5 months ago toggle.php 9 months ago video.php 7 months ago wordpress.php 1 year ago
tabs.php
636 lines
1 <?php
2 namespace Elementor;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
9 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
10
11 /**
12 * Elementor tabs widget.
13 *
14 * Elementor widget that displays vertical or horizontal tabs with different
15 * pieces of content.
16 *
17 * @since 1.0.0
18 */
19 class Widget_Tabs extends Widget_Base {
20
21 /**
22 * Get widget name.
23 *
24 * Retrieve tabs widget name.
25 *
26 * @since 1.0.0
27 * @access public
28 *
29 * @return string Widget name.
30 */
31 public function get_name() {
32 return 'tabs';
33 }
34
35 /**
36 * Get widget title.
37 *
38 * Retrieve tabs widget title.
39 *
40 * @since 1.0.0
41 * @access public
42 *
43 * @return string Widget title.
44 */
45 public function get_title() {
46 return esc_html__( 'Tabs', 'elementor' );
47 }
48
49 /**
50 * Get widget icon.
51 *
52 * Retrieve tabs widget icon.
53 *
54 * @since 1.0.0
55 * @access public
56 *
57 * @return string Widget icon.
58 */
59 public function get_icon() {
60 return 'eicon-tabs';
61 }
62
63 /**
64 * Get widget keywords.
65 *
66 * Retrieve the list of keywords the widget belongs to.
67 *
68 * @since 2.1.0
69 * @access public
70 *
71 * @return array Widget keywords.
72 */
73 public function get_keywords() {
74 return [ 'tabs', 'accordion', 'toggle' ];
75 }
76
77 protected function is_dynamic_content(): bool {
78 return false;
79 }
80
81 /**
82 * Get style dependencies.
83 *
84 * Retrieve the list of style dependencies the widget requires.
85 *
86 * @since 3.24.0
87 * @access public
88 *
89 * @return array Widget style dependencies.
90 */
91 public function get_style_depends(): array {
92 return [ 'widget-tabs' ];
93 }
94
95 public function show_in_panel(): bool {
96 return ! Plugin::$instance->experiments->is_feature_active( 'nested-elements', true );
97 }
98
99 public function has_widget_inner_wrapper(): bool {
100 return ! Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
101 }
102
103 /**
104 * Register tabs widget controls.
105 *
106 * Adds different input fields to allow the user to change and customize the widget settings.
107 *
108 * @since 3.1.0
109 * @access protected
110 */
111 protected function register_controls() {
112 $start = is_rtl() ? 'end' : 'start';
113 $end = is_rtl() ? 'start' : 'end';
114
115 $this->start_controls_section(
116 'section_tabs',
117 [
118 'label' => esc_html__( 'Tabs', 'elementor' ),
119 ]
120 );
121
122 $repeater = new Repeater();
123
124 $repeater->add_control(
125 'tab_title',
126 [
127 'label' => esc_html__( 'Title', 'elementor' ),
128 'type' => Controls_Manager::TEXT,
129 'default' => esc_html__( 'Tab Title', 'elementor' ),
130 'placeholder' => esc_html__( 'Tab Title', 'elementor' ),
131 'label_block' => true,
132 'dynamic' => [
133 'active' => true,
134 ],
135 ]
136 );
137
138 $repeater->add_control(
139 'tab_content',
140 [
141 'label' => esc_html__( 'Content', 'elementor' ),
142 'default' => esc_html__( 'Tab Content', 'elementor' ),
143 'placeholder' => esc_html__( 'Tab Content', 'elementor' ),
144 'type' => Controls_Manager::WYSIWYG,
145 ]
146 );
147
148 $is_nested_tabs_active = Plugin::$instance->widgets_manager->get_widget_types( 'nested-tabs' );
149
150 if ( $is_nested_tabs_active ) {
151 $this->add_deprecation_message(
152 '3.8.0',
153 esc_html__(
154 'You are currently editing a Tabs Widget in its old version. Any new tabs widget dragged into the canvas will be the new Tab widget, with the improved Nested capabilities.',
155 'elementor'
156 ),
157 'nested-tabs'
158 );
159 }
160
161 $this->add_control(
162 'tabs',
163 [
164 'label' => esc_html__( 'Tabs Items', 'elementor' ),
165 'type' => Controls_Manager::REPEATER,
166 'fields' => $repeater->get_controls(),
167 'default' => [
168 [
169 'tab_title' => esc_html__( 'Tab #1', 'elementor' ),
170 'tab_content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
171 ],
172 [
173 'tab_title' => esc_html__( 'Tab #2', 'elementor' ),
174 'tab_content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
175 ],
176 ],
177 'title_field' => '{{{ tab_title }}}',
178 ]
179 );
180
181 $this->add_control(
182 'type',
183 [
184 'label' => esc_html__( 'Position', 'elementor' ),
185 'type' => Controls_Manager::CHOOSE,
186 'default' => 'horizontal',
187 'options' => [
188 'vertical' => [
189 'title' => esc_html__( 'Vertical', 'elementor' ),
190 'icon' => 'eicon-h-align-left',
191 ],
192 'horizontal' => [
193 'title' => esc_html__( 'Horizontal', 'elementor' ),
194 'icon' => 'eicon-v-align-top',
195 ],
196 ],
197 'classes' => 'elementor-control-start-end',
198 'prefix_class' => 'elementor-tabs-view-',
199 'separator' => 'before',
200 ]
201 );
202
203 $this->add_control(
204 'tabs_align_horizontal',
205 [
206 'label' => esc_html__( 'Alignment', 'elementor' ),
207 'type' => Controls_Manager::CHOOSE,
208 'options' => [
209 '' => [
210 'title' => esc_html__( 'Start', 'elementor' ),
211 'icon' => "eicon-align-$start-h",
212 ],
213 'center' => [
214 'title' => esc_html__( 'Center', 'elementor' ),
215 'icon' => 'eicon-align-center-h',
216 ],
217 'end' => [
218 'title' => esc_html__( 'End', 'elementor' ),
219 'icon' => "eicon-align-$end-h",
220 ],
221 'stretch' => [
222 'title' => esc_html__( 'Stretch', 'elementor' ),
223 'icon' => 'eicon-align-stretch-h',
224 ],
225 ],
226 'prefix_class' => 'elementor-tabs-alignment-',
227 'condition' => [
228 'type' => 'horizontal',
229 ],
230 ]
231 );
232
233 $this->add_control(
234 'tabs_align_vertical',
235 [
236 'label' => esc_html__( 'Alignment', 'elementor' ),
237 'type' => Controls_Manager::CHOOSE,
238 'options' => [
239 '' => [
240 'title' => esc_html__( 'Start', 'elementor' ),
241 'icon' => 'eicon-align-start-v',
242 ],
243 'center' => [
244 'title' => esc_html__( 'Center', 'elementor' ),
245 'icon' => 'eicon-align-center-v',
246 ],
247 'end' => [
248 'title' => esc_html__( 'End', 'elementor' ),
249 'icon' => 'eicon-align-end-v',
250 ],
251 'stretch' => [
252 'title' => esc_html__( 'Stretch', 'elementor' ),
253 'icon' => 'eicon-align-stretch-v',
254 ],
255 ],
256 'prefix_class' => 'elementor-tabs-alignment-',
257 'condition' => [
258 'type' => 'vertical',
259 ],
260 ]
261 );
262
263 $this->end_controls_section();
264
265 $this->start_controls_section(
266 'section_tabs_style',
267 [
268 'label' => esc_html__( 'Tabs', 'elementor' ),
269 'tab' => Controls_Manager::TAB_STYLE,
270 ]
271 );
272
273 $this->add_control(
274 'navigation_width',
275 [
276 'label' => esc_html__( 'Navigation Width', 'elementor' ),
277 'type' => Controls_Manager::SLIDER,
278 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
279 'default' => [
280 'unit' => '%',
281 ],
282 'range' => [
283 'px' => [
284 'min' => 10,
285 'max' => 500,
286 ],
287 '%' => [
288 'min' => 10,
289 'max' => 50,
290 ],
291 'em' => [
292 'min' => 1,
293 'max' => 50,
294 ],
295 'rem' => [
296 'min' => 1,
297 'max' => 50,
298 ],
299 ],
300 'selectors' => [
301 '{{WRAPPER}} .elementor-tabs-wrapper' => 'width: {{SIZE}}{{UNIT}}',
302 ],
303 'condition' => [
304 'type' => 'vertical',
305 ],
306 ]
307 );
308
309 $this->add_control(
310 'border_width',
311 [
312 'label' => esc_html__( 'Border Width', 'elementor' ),
313 'type' => Controls_Manager::SLIDER,
314 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
315 'default' => [
316 'size' => 1,
317 ],
318 'range' => [
319 'px' => [
320 'max' => 20,
321 ],
322 'em' => [
323 'max' => 2,
324 ],
325 ],
326 'selectors' => [
327 '{{WRAPPER}} .elementor-tab-title, {{WRAPPER}} .elementor-tab-title:before, {{WRAPPER}} .elementor-tab-title:after, {{WRAPPER}} .elementor-tab-content, {{WRAPPER}} .elementor-tabs-content-wrapper' => 'border-width: {{SIZE}}{{UNIT}};',
328 ],
329 ]
330 );
331
332 $this->add_control(
333 'border_color',
334 [
335 'label' => esc_html__( 'Border Color', 'elementor' ),
336 'type' => Controls_Manager::COLOR,
337 'selectors' => [
338 '{{WRAPPER}} .elementor-tab-mobile-title, {{WRAPPER}} .elementor-tab-desktop-title.elementor-active, {{WRAPPER}} .elementor-tab-title:before, {{WRAPPER}} .elementor-tab-title:after, {{WRAPPER}} .elementor-tab-content, {{WRAPPER}} .elementor-tabs-content-wrapper' => 'border-color: {{VALUE}};',
339 ],
340 ]
341 );
342
343 $this->add_control(
344 'background_color',
345 [
346 'label' => esc_html__( 'Background Color', 'elementor' ),
347 'type' => Controls_Manager::COLOR,
348 'selectors' => [
349 '{{WRAPPER}} .elementor-tab-desktop-title.elementor-active' => 'background-color: {{VALUE}};',
350 '{{WRAPPER}} .elementor-tabs-content-wrapper' => 'background-color: {{VALUE}};',
351 ],
352 ]
353 );
354
355 $this->add_control(
356 'heading_title',
357 [
358 'label' => esc_html__( 'Title', 'elementor' ),
359 'type' => Controls_Manager::HEADING,
360 'separator' => 'before',
361 ]
362 );
363
364 $this->add_control(
365 'tab_color',
366 [
367 'label' => esc_html__( 'Color', 'elementor' ),
368 'type' => Controls_Manager::COLOR,
369 'selectors' => [
370 '{{WRAPPER}} .elementor-tab-title, {{WRAPPER}} .elementor-tab-title a' => 'color: {{VALUE}}',
371 ],
372 'global' => [
373 'default' => Global_Colors::COLOR_PRIMARY,
374 ],
375 ]
376 );
377
378 $this->add_control(
379 'tab_active_color',
380 [
381 'label' => esc_html__( 'Active Color', 'elementor' ),
382 'type' => Controls_Manager::COLOR,
383 'selectors' => [
384 '{{WRAPPER}} .elementor-tab-title.elementor-active,
385 {{WRAPPER}} .elementor-tab-title.elementor-active a' => 'color: {{VALUE}}',
386 ],
387 'global' => [
388 'default' => Global_Colors::COLOR_ACCENT,
389 ],
390 ]
391 );
392
393 $this->add_group_control(
394 Group_Control_Typography::get_type(),
395 [
396 'name' => 'tab_typography',
397 'selector' => '{{WRAPPER}} .elementor-tab-title',
398 'global' => [
399 'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
400 ],
401 ]
402 );
403
404 $this->add_group_control(
405 Group_Control_Text_Stroke::get_type(),
406 [
407 'name' => 'text_stroke',
408 'selector' => '{{WRAPPER}} .elementor-tab-title',
409 ]
410 );
411
412 $this->add_group_control(
413 Group_Control_Text_Shadow::get_type(),
414 [
415 'name' => 'title_shadow',
416 'selector' => '{{WRAPPER}} .elementor-tab-title',
417 ]
418 );
419
420 $this->add_control(
421 'title_align',
422 [
423 'label' => esc_html__( 'Alignment', 'elementor' ),
424 'type' => Controls_Manager::CHOOSE,
425 'options' => [
426 'start' => [
427 'title' => esc_html__( 'Start', 'elementor' ),
428 'icon' => 'eicon-text-align-left',
429 ],
430 'center' => [
431 'title' => esc_html__( 'Center', 'elementor' ),
432 'icon' => 'eicon-text-align-center',
433 ],
434 'end' => [
435 'title' => esc_html__( 'End', 'elementor' ),
436 'icon' => 'eicon-text-align-right',
437 ],
438 ],
439 'classes' => 'elementor-control-start-end',
440 'selectors_dictionary' => [
441 'left' => is_rtl() ? 'end' : 'start',
442 'right' => is_rtl() ? 'start' : 'end',
443 ],
444 'selectors' => [
445 '{{WRAPPER}} .elementor-tab-title' => 'text-align: {{VALUE}};',
446 ],
447 'condition' => [
448 'tabs_align' => 'stretch',
449 ],
450 ]
451 );
452
453 $this->add_control(
454 'heading_content',
455 [
456 'label' => esc_html__( 'Content', 'elementor' ),
457 'type' => Controls_Manager::HEADING,
458 'separator' => 'before',
459 ]
460 );
461
462 $this->add_control(
463 'content_color',
464 [
465 'label' => esc_html__( 'Color', 'elementor' ),
466 'type' => Controls_Manager::COLOR,
467 'selectors' => [
468 '{{WRAPPER}} .elementor-tab-content' => 'color: {{VALUE}};',
469 ],
470 'global' => [
471 'default' => Global_Colors::COLOR_TEXT,
472 ],
473 ]
474 );
475
476 $this->add_group_control(
477 Group_Control_Typography::get_type(),
478 [
479 'name' => 'content_typography',
480 'selector' => '{{WRAPPER}} .elementor-tab-content',
481 'global' => [
482 'default' => Global_Typography::TYPOGRAPHY_TEXT,
483 ],
484 ]
485 );
486
487 $this->add_group_control(
488 Group_Control_Text_Shadow::get_type(),
489 [
490 'name' => 'content_shadow',
491 'selector' => '{{WRAPPER}} .elementor-tab-content',
492 ]
493 );
494
495 $this->end_controls_section();
496 }
497
498 /**
499 * Render tabs widget output on the frontend.
500 *
501 * Written in PHP and used to generate the final HTML.
502 *
503 * @since 1.0.0
504 * @access protected
505 */
506 protected function render() {
507 $tabs = $this->get_settings_for_display( 'tabs' );
508
509 $id_int = substr( $this->get_id_int(), 0, 3 );
510
511 $this->add_render_attribute( 'elementor-tabs', 'class', 'elementor-tabs' );
512
513 ?>
514 <div <?php $this->print_render_attribute_string( 'elementor-tabs' ); ?>>
515 <div class="elementor-tabs-wrapper" role="tablist" >
516 <?php
517 foreach ( $tabs as $index => $item ) :
518 $tab_count = $index + 1;
519 $tab_title_setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $index );
520
521 $this->add_render_attribute( $tab_title_setting_key, [
522 'id' => 'elementor-tab-title-' . $id_int . $tab_count,
523 'class' => [ 'elementor-tab-title', 'elementor-tab-desktop-title' ],
524 'aria-selected' => 1 === $tab_count ? 'true' : 'false',
525 'data-tab' => $tab_count,
526 'role' => 'tab',
527 'tabindex' => 1 === $tab_count ? '0' : '-1',
528 'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
529 'aria-expanded' => 'false',
530 ] );
531 ?>
532 <div <?php $this->print_render_attribute_string( $tab_title_setting_key ); ?>><?php
533 // PHPCS - the main text of a widget should not be escaped.
534 echo $item['tab_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
535 ?></div>
536 <?php endforeach; ?>
537 </div>
538 <div class="elementor-tabs-content-wrapper" role="tablist" aria-orientation="vertical">
539 <?php
540 foreach ( $tabs as $index => $item ) :
541 $tab_count = $index + 1;
542 $hidden = 1 === $tab_count ? 'false' : 'hidden';
543 $tab_content_setting_key = $this->get_repeater_setting_key( 'tab_content', 'tabs', $index );
544
545 $tab_title_mobile_setting_key = $this->get_repeater_setting_key( 'tab_title_mobile', 'tabs', $tab_count );
546
547 $this->add_render_attribute( $tab_content_setting_key, [
548 'id' => 'elementor-tab-content-' . $id_int . $tab_count,
549 'class' => [ 'elementor-tab-content', 'elementor-clearfix' ],
550 'data-tab' => $tab_count,
551 'role' => 'tabpanel',
552 'aria-labelledby' => 'elementor-tab-title-' . $id_int . $tab_count,
553 'tabindex' => '0',
554 'hidden' => $hidden,
555 ] );
556
557 $this->add_render_attribute( $tab_title_mobile_setting_key, [
558 'class' => [ 'elementor-tab-title', 'elementor-tab-mobile-title' ],
559 'aria-selected' => 1 === $tab_count ? 'true' : 'false',
560 'data-tab' => $tab_count,
561 'role' => 'tab',
562 'tabindex' => 1 === $tab_count ? '0' : '-1',
563 'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
564 'aria-expanded' => 'false',
565 ] );
566
567 $this->add_inline_editing_attributes( $tab_content_setting_key, 'advanced' );
568 ?>
569 <div <?php $this->print_render_attribute_string( $tab_title_mobile_setting_key ); ?>><?php
570 $this->print_unescaped_setting( 'tab_title', 'tabs', $index );
571 ?></div>
572 <div <?php $this->print_render_attribute_string( $tab_content_setting_key ); ?>><?php
573 $this->print_text_editor( $item['tab_content'] );
574 ?></div>
575 <?php endforeach; ?>
576 </div>
577 </div>
578 <?php
579 }
580
581 /**
582 * Render tabs widget output in the editor.
583 *
584 * Written as a Backbone JavaScript template and used to generate the live preview.
585 *
586 * @since 2.9.0
587 * @access protected
588 */
589 protected function content_template() {
590 ?>
591 <div class="elementor-tabs" role="tablist" aria-orientation="vertical">
592 <# if ( settings.tabs ) {
593 var elementUid = view.getIDInt().toString().substr( 0, 3 ); #>
594 <div class="elementor-tabs-wrapper" role="tablist">
595 <# _.each( settings.tabs, function( item, index ) {
596 var tabCount = index + 1,
597 tabUid = elementUid + tabCount,
598 tabTitleKey = 'tab-title-' + tabUid;
599
600 view.addRenderAttribute( tabTitleKey, {
601 'id': 'elementor-tab-title-' + tabUid,
602 'class': [ 'elementor-tab-title','elementor-tab-desktop-title' ],
603 'data-tab': tabCount,
604 'role': 'tab',
605 'tabindex': 1 === tabCount ? '0' : '-1',
606 'aria-controls': 'elementor-tab-content-' + tabUid,
607 'aria-expanded': 'false',
608 } );
609 #>
610 <div {{{ view.getRenderAttributeString( tabTitleKey ) }}}>{{{ item.tab_title }}}</div>
611 <# } ); #>
612 </div>
613 <div class="elementor-tabs-content-wrapper">
614 <# _.each( settings.tabs, function( item, index ) {
615 var tabCount = index + 1,
616 tabContentKey = view.getRepeaterSettingKey( 'tab_content', 'tabs',index );
617
618 view.addRenderAttribute( tabContentKey, {
619 'id': 'elementor-tab-content-' + elementUid + tabCount,
620 'class': [ 'elementor-tab-content', 'elementor-clearfix', 'elementor-repeater-item-' + item._id ],
621 'data-tab': tabCount,
622 'role' : 'tabpanel',
623 'aria-labelledby' : 'elementor-tab-title-' + elementUid + tabCount
624 } );
625
626 view.addInlineEditingAttributes( tabContentKey, 'advanced' ); #>
627 <div class="elementor-tab-title elementor-tab-mobile-title" data-tab="{{ tabCount }}" role="tab">{{{ item.tab_title }}}</div>
628 <div {{{ view.getRenderAttributeString( tabContentKey ) }}}>{{{ item.tab_content }}}</div>
629 <# } ); #>
630 </div>
631 <# } #>
632 </div>
633 <?php
634 }
635 }
636