PluginProbe
Elementor Website Builder – more than just a page builder / 3.1.2
Elementor Website Builder – more than just a page builder v3.1.2
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.1.2, at includes/widgets/toggle.php

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