PluginProbe
Elementor Website Builder – more than just a page builder / 3.0.13
Elementor Website Builder – more than just a page builder v3.0.13
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / includes / widgets / toggle.php

toggle.php in Elementor Website Builder – more than just a page builder 3.0.13, at includes/widgets/toggle.php

640 lines 17.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 toggle widget.
13 *
14 * Elementor widget that displays a collapsible display of content in an toggle
15 * style, allowing the user to open multiple items.
16 *
17 * @since 1.0.0
18 */
19 class Widget_Toggle extends Widget_Base {
20
21 /**
22 * Get widget name.
23 *
24 * Retrieve toggle 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 'toggle';
33 }
34
35 /**
36 * Get widget title.
37 *
38 * Retrieve toggle 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 __( 'Toggle', 'elementor' );
47 }
48
49 /**
50 * Get widget icon.
51 *
52 * Retrieve toggle 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-toggle';
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 /**
78 * Register toggle widget controls.
79 *
80 * Adds different input fields to allow the user to change and customize the widget settings.
81 *
82 * @since 1.0.0
83 * @access protected
84 */
85 protected function _register_controls() {
86 $this->start_controls_section(
87 'section_toggle',
88 [
89 'label' => __( 'Toggle', 'elementor' ),
90 ]
91 );
92
93 $repeater = new Repeater();
94
95 $repeater->add_control(
96 'tab_title',
97 [
98 'label' => __( 'Title & Description', 'elementor' ),
99 'type' => Controls_Manager::TEXT,
100 'default' => __( 'Toggle Title', 'elementor' ),
101 'label_block' => true,
102 'dynamic' => [
103 'active' => true,
104 ],
105 ]
106 );
107
108 $repeater->add_control(
109 'tab_content',
110 [
111 'label' => __( 'Content', 'elementor' ),
112 'type' => Controls_Manager::WYSIWYG,
113 'default' => __( 'Toggle Content', 'elementor' ),
114 'show_label' => false,
115 ]
116 );
117
118 $this->add_control(
119 'tabs',
120 [
121 'label' => __( 'Toggle Items', 'elementor' ),
122 'type' => Controls_Manager::REPEATER,
123 'fields' => $repeater->get_controls(),
124 'default' => [
125 [
126 'tab_title' => __( 'Toggle #1', 'elementor' ),
127 'tab_content' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
128 ],
129 [
130 'tab_title' => __( 'Toggle #2', 'elementor' ),
131 'tab_content' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
132 ],
133 ],
134 'title_field' => '{{{ tab_title }}}',
135 ]
136 );
137
138 $this->add_control(
139 'view',
140 [
141 'label' => __( 'View', 'elementor' ),
142 'type' => Controls_Manager::HIDDEN,
143 'default' => 'traditional',
144 ]
145 );
146
147 $this->add_control(
148 'selected_icon',
149 [
150 'label' => __( 'Icon', 'elementor' ),
151 'type' => Controls_Manager::ICONS,
152 'separator' => 'before',
153 'fa4compatibility' => 'icon',
154 'default' => [
155 'value' => 'fas fa-caret' . ( is_rtl() ? '-left' : '-right' ),
156 'library' => 'fa-solid',
157 ],
158 'recommended' => [
159 'fa-solid' => [
160 'chevron-down',
161 'angle-down',
162 'angle-double-down',
163 'caret-down',
164 'caret-square-down',
165 ],
166 'fa-regular' => [
167 'caret-square-down',
168 ],
169 ],
170 'label_block' => false,
171 'skin' => 'inline',
172 ]
173 );
174
175 $this->add_control(
176 'selected_active_icon',
177 [
178 'label' => __( 'Active Icon', 'elementor' ),
179 'type' => Controls_Manager::ICONS,
180 'fa4compatibility' => 'icon_active',
181 'default' => [
182 'value' => 'fas fa-caret-up',
183 'library' => 'fa-solid',
184 ],
185 'recommended' => [
186 'fa-solid' => [
187 'chevron-up',
188 'angle-up',
189 'angle-double-up',
190 'caret-up',
191 'caret-square-up',
192 ],
193 'fa-regular' => [
194 'caret-square-up',
195 ],
196 ],
197 'skin' => 'inline',
198 'label_block' => false,
199 'condition' => [
200 'selected_icon[value]!' => '',
201 ],
202 ]
203 );
204
205 $this->add_control(
206 'title_html_tag',
207 [
208 'label' => __( 'Title HTML Tag', 'elementor' ),
209 'type' => Controls_Manager::SELECT,
210 'options' => [
211 'h1' => 'H1',
212 'h2' => 'H2',
213 'h3' => 'H3',
214 'h4' => 'H4',
215 'h5' => 'H5',
216 'h6' => 'H6',
217 'div' => 'div',
218 ],
219 'default' => 'div',
220 'separator' => 'before',
221 ]
222 );
223
224 $this->end_controls_section();
225
226 $this->start_controls_section(
227 'section_toggle_style',
228 [
229 'label' => __( 'Toggle', 'elementor' ),
230 'tab' => Controls_Manager::TAB_STYLE,
231 ]
232 );
233
234 $this->add_control(
235 'border_width',
236 [
237 'label' => __( 'Border Width', 'elementor' ),
238 'type' => Controls_Manager::SLIDER,
239 'range' => [
240 'px' => [
241 'min' => 0,
242 'max' => 10,
243 ],
244 ],
245 'selectors' => [
246 '{{WRAPPER}} .elementor-toggle .elementor-tab-title' => 'border-width: {{SIZE}}{{UNIT}};',
247 '{{WRAPPER}} .elementor-toggle .elementor-tab-content' => 'border-width: {{SIZE}}{{UNIT}};',
248 ],
249 ]
250 );
251
252 $this->add_control(
253 'border_color',
254 [
255 'label' => __( 'Border Color', 'elementor' ),
256 'type' => Controls_Manager::COLOR,
257 'selectors' => [
258 '{{WRAPPER}} .elementor-toggle .elementor-tab-content' => 'border-bottom-color: {{VALUE}};',
259 '{{WRAPPER}} .elementor-toggle .elementor-tab-title' => 'border-color: {{VALUE}};',
260 ],
261 ]
262 );
263
264 $this->add_responsive_control(
265 'space_between',
266 [
267 'label' => __( 'Space Between', 'elementor' ),
268 'type' => Controls_Manager::SLIDER,
269 'range' => [
270 'px' => [
271 'min' => 0,
272 'max' => 100,
273 ],
274 ],
275 'selectors' => [
276 '{{WRAPPER}} .elementor-toggle .elementor-toggle-item:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}}',
277 ],
278 ]
279 );
280
281 $this->add_group_control(
282 Group_Control_Box_Shadow::get_type(),
283 [
284 'name' => 'box_shadow',
285 'selector' => '{{WRAPPER}} .elementor-toggle .elementor-toggle-item',
286 ]
287 );
288
289 $this->end_controls_section();
290
291 $this->start_controls_section(
292 'section_toggle_style_title',
293 [
294 'label' => __( 'Title', 'elementor' ),
295 'tab' => Controls_Manager::TAB_STYLE,
296 ]
297 );
298
299 $this->add_control(
300 'title_background',
301 [
302 'label' => __( 'Background', 'elementor' ),
303 'type' => Controls_Manager::COLOR,
304 'selectors' => [
305 '{{WRAPPER}} .elementor-toggle .elementor-tab-title' => 'background-color: {{VALUE}};',
306 ],
307 ]
308 );
309
310 // The title selector specificity is to override Theme Style
311 $this->add_control(
312 'title_color',
313 [
314 'label' => __( 'Color', 'elementor' ),
315 'type' => Controls_Manager::COLOR,
316 'selectors' => [
317 '{{WRAPPER}} .elementor-toggle-title, {{WRAPPER}} .elementor-toggle-icon' => 'color: {{VALUE}};',
318 ],
319 'global' => [
320 'default' => Global_Colors::COLOR_PRIMARY,
321 ],
322 ]
323 );
324
325 $this->add_control(
326 'tab_active_color',
327 [
328 'label' => __( 'Active Color', 'elementor' ),
329 'type' => Controls_Manager::COLOR,
330 'selectors' => [
331 '{{WRAPPER}} .elementor-tab-title.elementor-active a, {{WRAPPER}} .elementor-tab-title.elementor-active .elementor-toggle-icon' => 'color: {{VALUE}};',
332 ],
333 'global' => [
334 'default' => Global_Colors::COLOR_ACCENT,
335 ],
336 ]
337 );
338
339 $this->add_group_control(
340 Group_Control_Typography::get_type(),
341 [
342 'name' => 'title_typography',
343 'selector' => '{{WRAPPER}} .elementor-toggle .elementor-toggle-title',
344 'global' => [
345 'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
346 ],
347 ]
348 );
349
350 $this->add_responsive_control(
351 'title_padding',
352 [
353 'label' => __( 'Padding', 'elementor' ),
354 'type' => Controls_Manager::DIMENSIONS,
355 'size_units' => [ 'px', 'em', '%' ],
356 'selectors' => [
357 '{{WRAPPER}} .elementor-toggle .elementor-tab-title' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
358 ],
359 ]
360 );
361
362 $this->end_controls_section();
363
364 $this->start_controls_section(
365 'section_toggle_style_icon',
366 [
367 'label' => __( 'Icon', 'elementor' ),
368 'tab' => Controls_Manager::TAB_STYLE,
369 'condition' => [
370 'selected_icon[value]!' => '',
371 ],
372 ]
373 );
374
375 $this->add_control(
376 'icon_align',
377 [
378 'label' => __( 'Alignment', 'elementor' ),
379 'type' => Controls_Manager::CHOOSE,
380 'options' => [
381 'left' => [
382 'title' => __( 'Start', 'elementor' ),
383 'icon' => 'eicon-h-align-left',
384 ],
385 'right' => [
386 'title' => __( 'End', 'elementor' ),
387 'icon' => 'eicon-h-align-right',
388 ],
389 ],
390 'default' => is_rtl() ? 'right' : 'left',
391 'toggle' => false,
392 ]
393 );
394
395 $this->add_control(
396 'icon_color',
397 [
398 'label' => __( 'Color', 'elementor' ),
399 'type' => Controls_Manager::COLOR,
400 'selectors' => [
401 '{{WRAPPER}} .elementor-toggle .elementor-tab-title .elementor-toggle-icon i:before' => 'color: {{VALUE}};',
402 '{{WRAPPER}} .elementor-toggle .elementor-tab-title .elementor-toggle-icon svg' => 'fill: {{VALUE}};',
403 ],
404 ]
405 );
406
407 $this->add_control(
408 'icon_active_color',
409 [
410 'label' => __( 'Active Color', 'elementor' ),
411 'type' => Controls_Manager::COLOR,
412 'selectors' => [
413 '{{WRAPPER}} .elementor-toggle .elementor-tab-title.elementor-active .elementor-toggle-icon i:before' => 'color: {{VALUE}};',
414 '{{WRAPPER}} .elementor-toggle .elementor-tab-title.elementor-active .elementor-toggle-icon svg' => 'fill: {{VALUE}};',
415 ],
416 ]
417 );
418
419 $this->add_responsive_control(
420 'icon_space',
421 [
422 'label' => __( 'Spacing', 'elementor' ),
423 'type' => Controls_Manager::SLIDER,
424 'range' => [
425 'px' => [
426 'min' => 0,
427 'max' => 100,
428 ],
429 ],
430 'selectors' => [
431 '{{WRAPPER}} .elementor-toggle .elementor-toggle-icon.elementor-toggle-icon-left' => 'margin-right: {{SIZE}}{{UNIT}};',
432 '{{WRAPPER}} .elementor-toggle .elementor-toggle-icon.elementor-toggle-icon-right' => 'margin-left: {{SIZE}}{{UNIT}};',
433 ],
434 ]
435 );
436
437 $this->end_controls_section();
438
439 $this->start_controls_section(
440 'section_toggle_style_content',
441 [
442 'label' => __( 'Content', 'elementor' ),
443 'tab' => Controls_Manager::TAB_STYLE,
444 ]
445 );
446
447 $this->add_control(
448 'content_background_color',
449 [
450 'label' => __( 'Background', 'elementor' ),
451 'type' => Controls_Manager::COLOR,
452 'selectors' => [
453 '{{WRAPPER}} .elementor-toggle .elementor-tab-content' => 'background-color: {{VALUE}};',
454 ],
455 ]
456 );
457
458 $this->add_control(
459 'content_color',
460 [
461 'label' => __( 'Color', 'elementor' ),
462 'type' => Controls_Manager::COLOR,
463 'selectors' => [
464 '{{WRAPPER}} .elementor-toggle .elementor-tab-content' => 'color: {{VALUE}};',
465 ],
466 'global' => [
467 'default' => Global_Colors::COLOR_TEXT,
468 ],
469 ]
470 );
471
472 $this->add_group_control(
473 Group_Control_Typography::get_type(),
474 [
475 'name' => 'content_typography',
476 'selector' => '{{WRAPPER}} .elementor-toggle .elementor-tab-content',
477 'global' => [
478 'default' => Global_Typography::TYPOGRAPHY_TEXT,
479 ],
480 ]
481 );
482
483 $this->add_responsive_control(
484 'content_padding',
485 [
486 'label' => __( 'Padding', 'elementor' ),
487 'type' => Controls_Manager::DIMENSIONS,
488 'size_units' => [ 'px', 'em', '%' ],
489 'selectors' => [
490 '{{WRAPPER}} .elementor-toggle .elementor-tab-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
491 ],
492 ]
493 );
494
495 $this->end_controls_section();
496 }
497
498 /**
499 * Render toggle 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 $settings = $this->get_settings_for_display();
508
509 $id_int = substr( $this->get_id_int(), 0, 3 );
510 $migrated = isset( $settings['__fa4_migrated']['selected_icon'] );
511
512 if ( ! isset( $settings['icon'] ) && ! Icons_Manager::is_migration_allowed() ) {
513 // @todo: remove when deprecated
514 // added as bc in 2.6
515 // add old default
516 $settings['icon'] = 'fa fa-caret' . ( is_rtl() ? '-left' : '-right' );
517 $settings['icon_active'] = 'fa fa-caret-up';
518 $settings['icon_align'] = $this->get_settings( 'icon_align' );
519 }
520
521 $is_new = empty( $settings['icon'] ) && Icons_Manager::is_migration_allowed();
522 $has_icon = ( ! $is_new || ! empty( $settings['selected_icon']['value'] ) );
523
524 ?>
525 <div class="elementor-toggle" role="tablist">
526 <?php
527 foreach ( $settings['tabs'] as $index => $item ) :
528 $tab_count = $index + 1;
529
530 $tab_title_setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $index );
531
532 $tab_content_setting_key = $this->get_repeater_setting_key( 'tab_content', 'tabs', $index );
533
534 $this->add_render_attribute( $tab_title_setting_key, [
535 'id' => 'elementor-tab-title-' . $id_int . $tab_count,
536 'class' => [ 'elementor-tab-title' ],
537 'data-tab' => $tab_count,
538 'role' => 'tab',
539 'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
540 ] );
541
542 $this->add_render_attribute( $tab_content_setting_key, [
543 'id' => 'elementor-tab-content-' . $id_int . $tab_count,
544 'class' => [ 'elementor-tab-content', 'elementor-clearfix' ],
545 'data-tab' => $tab_count,
546 'role' => 'tabpanel',
547 'aria-labelledby' => 'elementor-tab-title-' . $id_int . $tab_count,
548 ] );
549
550 $this->add_inline_editing_attributes( $tab_content_setting_key, 'advanced' );
551 ?>
552 <div class="elementor-toggle-item">
553 <<?php echo esc_html( $settings['title_html_tag'] ); ?> <?php echo $this->get_render_attribute_string( $tab_title_setting_key ); ?>>
554 <?php if ( $has_icon ) : ?>
555 <span class="elementor-toggle-icon elementor-toggle-icon-<?php echo esc_attr( $settings['icon_align'] ); ?>" aria-hidden="true">
556 <?php
557 if ( $is_new || $migrated ) { ?>
558 <span class="elementor-toggle-icon-closed"><?php Icons_Manager::render_icon( $settings['selected_icon'] ); ?></span>
559 <span class="elementor-toggle-icon-opened"><?php Icons_Manager::render_icon( $settings['selected_active_icon'], [ 'class' => 'elementor-toggle-icon-opened' ] ); ?></span>
560 <?php } else { ?>
561 <i class="elementor-toggle-icon-closed <?php echo esc_attr( $settings['icon'] ); ?>"></i>
562 <i class="elementor-toggle-icon-opened <?php echo esc_attr( $settings['icon_active'] ); ?>"></i>
563 <?php } ?>
564 </span>
565 <?php endif; ?>
566 <a href="" class="elementor-toggle-title"><?php echo $item['tab_title']; ?></a>
567 </<?php echo esc_html( $settings['title_html_tag'] ); ?>>
568 <div <?php echo $this->get_render_attribute_string( $tab_content_setting_key ); ?>><?php echo $this->parse_text_editor( $item['tab_content'] ); ?></div>
569 </div>
570 <?php endforeach; ?>
571 </div>
572 <?php
573 }
574
575 /**
576 * Render toggle widget output in the editor.
577 *
578 * Written as a Backbone JavaScript template and used to generate the live preview.
579 *
580 * @since 2.9.0
581 * @access protected
582 */
583 protected function content_template() {
584 ?>
585 <div class="elementor-toggle" role="tablist">
586 <#
587 if ( settings.tabs ) {
588 var tabindex = view.getIDInt().toString().substr( 0, 3 ),
589 iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, {}, 'i' , 'object' ),
590 iconActiveHTML = elementor.helpers.renderIcon( view, settings.selected_active_icon, {}, 'i' , 'object' ),
591 migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' );
592
593 _.each( settings.tabs, function( item, index ) {
594 var tabCount = index + 1,
595 tabTitleKey = view.getRepeaterSettingKey( 'tab_title', 'tabs', index ),
596 tabContentKey = view.getRepeaterSettingKey( 'tab_content', 'tabs', index );
597
598 view.addRenderAttribute( tabTitleKey, {
599 'id': 'elementor-tab-title-' + tabindex + tabCount,
600 'class': [ 'elementor-tab-title' ],
601 'data-tab': tabCount,
602 'role': 'tab',
603 'aria-controls': 'elementor-tab-content-' + tabindex + tabCount
604 } );
605
606 view.addRenderAttribute( tabContentKey, {
607 'id': 'elementor-tab-content-' + tabindex + tabCount,
608 'class': [ 'elementor-tab-content', 'elementor-clearfix' ],
609 'data-tab': tabCount,
610 'role': 'tabpanel',
611 'aria-labelledby': 'elementor-tab-title-' + tabindex + tabCount
612 } );
613
614 view.addInlineEditingAttributes( tabContentKey, 'advanced' );
615 #>
616 <div class="elementor-toggle-item">
617 <{{{ settings.title_html_tag }}} {{{ view.getRenderAttributeString( tabTitleKey ) }}}>
618 <# if ( settings.icon || settings.selected_icon ) { #>
619 <span class="elementor-toggle-icon elementor-toggle-icon-{{ settings.icon_align }}" aria-hidden="true">
620 <# if ( iconHTML && iconHTML.rendered && ( ! settings.icon || migrated ) ) { #>
621 <span class="elementor-toggle-icon-closed">{{{ iconHTML.value }}}</span>
622 <span class="elementor-toggle-icon-opened">{{{ iconActiveHTML.value }}}</span>
623 <# } else { #>
624 <i class="elementor-toggle-icon-closed {{ settings.icon }}"></i>
625 <i class="elementor-toggle-icon-opened {{ settings.icon_active }}"></i>
626 <# } #>
627 </span>
628 <# } #>
629 <a href="" class="elementor-toggle-title">{{{ item.tab_title }}}</a>
630 </{{{ settings.title_html_tag }}}>
631 <div {{{ view.getRenderAttributeString( tabContentKey ) }}}>{{{ item.tab_content }}}</div>
632 </div>
633 <#
634 } );
635 } #>
636 </div>
637 <?php
638 }
639 }
640