balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

tabs.php (15737B)


      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 	/**
     78 	 * Register tabs 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_tabs',
     88 			[
     89 				'label' => esc_html__( 'Tabs', 'elementor' ),
     90 			]
     91 		);
     92 
     93 		$repeater = new Repeater();
     94 
     95 		$repeater->add_control(
     96 			'tab_title',
     97 			[
     98 				'label' => esc_html__( 'Title & Description', 'elementor' ),
     99 				'type' => Controls_Manager::TEXT,
    100 				'default' => esc_html__( 'Tab Title', 'elementor' ),
    101 				'placeholder' => esc_html__( 'Tab Title', 'elementor' ),
    102 				'label_block' => true,
    103 				'dynamic' => [
    104 					'active' => true,
    105 				],
    106 			]
    107 		);
    108 
    109 		$repeater->add_control(
    110 			'tab_content',
    111 			[
    112 				'label' => esc_html__( 'Content', 'elementor' ),
    113 				'default' => esc_html__( 'Tab Content', 'elementor' ),
    114 				'placeholder' => esc_html__( 'Tab Content', 'elementor' ),
    115 				'type' => Controls_Manager::WYSIWYG,
    116 				'show_label' => false,
    117 			]
    118 		);
    119 
    120 		$this->add_control(
    121 			'tabs',
    122 			[
    123 				'label' => esc_html__( 'Tabs Items', 'elementor' ),
    124 				'type' => Controls_Manager::REPEATER,
    125 				'fields' => $repeater->get_controls(),
    126 				'default' => [
    127 					[
    128 						'tab_title' => esc_html__( 'Tab #1', 'elementor' ),
    129 						'tab_content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
    130 					],
    131 					[
    132 						'tab_title' => esc_html__( 'Tab #2', 'elementor' ),
    133 						'tab_content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
    134 					],
    135 				],
    136 				'title_field' => '{{{ tab_title }}}',
    137 			]
    138 		);
    139 
    140 		$this->add_control(
    141 			'view',
    142 			[
    143 				'label' => esc_html__( 'View', 'elementor' ),
    144 				'type' => Controls_Manager::HIDDEN,
    145 				'default' => 'traditional',
    146 			]
    147 		);
    148 
    149 		$this->add_control(
    150 			'type',
    151 			[
    152 				'label' => esc_html__( 'Position', 'elementor' ),
    153 				'type' => Controls_Manager::SELECT,
    154 				'default' => 'horizontal',
    155 				'options' => [
    156 					'horizontal' => esc_html__( 'Horizontal', 'elementor' ),
    157 					'vertical' => esc_html__( 'Vertical', 'elementor' ),
    158 				],
    159 				'prefix_class' => 'elementor-tabs-view-',
    160 				'separator' => 'before',
    161 			]
    162 		);
    163 
    164 		$this->add_control(
    165 			'tabs_align_horizontal',
    166 			[
    167 				'label' => esc_html__( 'Alignment', 'elementor' ),
    168 				'type' => Controls_Manager::CHOOSE,
    169 				'options' => [
    170 					'' => [
    171 						'title' => esc_html__( 'Start', 'elementor' ),
    172 						'icon' => 'eicon-h-align-left',
    173 					],
    174 					'center' => [
    175 						'title' => esc_html__( 'Center', 'elementor' ),
    176 						'icon' => 'eicon-h-align-center',
    177 					],
    178 					'end' => [
    179 						'title' => esc_html__( 'End', 'elementor' ),
    180 						'icon' => 'eicon-h-align-right',
    181 					],
    182 					'stretch' => [
    183 						'title' => esc_html__( 'Justified', 'elementor' ),
    184 						'icon' => 'eicon-h-align-stretch',
    185 					],
    186 				],
    187 				'prefix_class' => 'elementor-tabs-alignment-',
    188 				'condition' => [
    189 					'type' => 'horizontal',
    190 				],
    191 			]
    192 		);
    193 
    194 		$this->add_control(
    195 			'tabs_align_vertical',
    196 			[
    197 				'label' => esc_html__( 'Alignment', 'elementor' ),
    198 				'type' => Controls_Manager::CHOOSE,
    199 				'options' => [
    200 					'' => [
    201 						'title' => esc_html__( 'Start', 'elementor' ),
    202 						'icon' => 'eicon-v-align-top',
    203 					],
    204 					'center' => [
    205 						'title' => esc_html__( 'Center', 'elementor' ),
    206 						'icon' => 'eicon-v-align-middle',
    207 					],
    208 					'end' => [
    209 						'title' => esc_html__( 'End', 'elementor' ),
    210 						'icon' => 'eicon-v-align-bottom',
    211 					],
    212 					'stretch' => [
    213 						'title' => esc_html__( 'Justified', 'elementor' ),
    214 						'icon' => 'eicon-v-align-stretch',
    215 					],
    216 				],
    217 				'prefix_class' => 'elementor-tabs-alignment-',
    218 				'condition' => [
    219 					'type' => 'vertical',
    220 				],
    221 			]
    222 		);
    223 
    224 		$this->end_controls_section();
    225 
    226 		$this->start_controls_section(
    227 			'section_tabs_style',
    228 			[
    229 				'label' => esc_html__( 'Tabs', 'elementor' ),
    230 				'tab' => Controls_Manager::TAB_STYLE,
    231 			]
    232 		);
    233 
    234 		$this->add_control(
    235 			'navigation_width',
    236 			[
    237 				'label' => esc_html__( 'Navigation Width', 'elementor' ),
    238 				'type' => Controls_Manager::SLIDER,
    239 				'default' => [
    240 					'unit' => '%',
    241 				],
    242 				'range' => [
    243 					'%' => [
    244 						'min' => 10,
    245 						'max' => 50,
    246 					],
    247 				],
    248 				'selectors' => [
    249 					'{{WRAPPER}} .elementor-tabs-wrapper' => 'width: {{SIZE}}{{UNIT}}',
    250 				],
    251 				'condition' => [
    252 					'type' => 'vertical',
    253 				],
    254 			]
    255 		);
    256 
    257 		$this->add_control(
    258 			'border_width',
    259 			[
    260 				'label' => esc_html__( 'Border Width', 'elementor' ),
    261 				'type' => Controls_Manager::SLIDER,
    262 				'default' => [
    263 					'size' => 1,
    264 				],
    265 				'range' => [
    266 					'px' => [
    267 						'min' => 0,
    268 						'max' => 10,
    269 					],
    270 				],
    271 				'selectors' => [
    272 					'{{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}};',
    273 				],
    274 			]
    275 		);
    276 
    277 		$this->add_control(
    278 			'border_color',
    279 			[
    280 				'label' => esc_html__( 'Border Color', 'elementor' ),
    281 				'type' => Controls_Manager::COLOR,
    282 				'selectors' => [
    283 					'{{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}};',
    284 				],
    285 			]
    286 		);
    287 
    288 		$this->add_control(
    289 			'background_color',
    290 			[
    291 				'label' => esc_html__( 'Background Color', 'elementor' ),
    292 				'type' => Controls_Manager::COLOR,
    293 				'selectors' => [
    294 					'{{WRAPPER}} .elementor-tab-desktop-title.elementor-active' => 'background-color: {{VALUE}};',
    295 					'{{WRAPPER}} .elementor-tabs-content-wrapper' => 'background-color: {{VALUE}};',
    296 				],
    297 			]
    298 		);
    299 
    300 		$this->add_control(
    301 			'heading_title',
    302 			[
    303 				'label' => esc_html__( 'Title', 'elementor' ),
    304 				'type' => Controls_Manager::HEADING,
    305 				'separator' => 'before',
    306 			]
    307 		);
    308 
    309 		$this->add_control(
    310 			'tab_color',
    311 			[
    312 				'label' => esc_html__( 'Color', 'elementor' ),
    313 				'type' => Controls_Manager::COLOR,
    314 				'selectors' => [
    315 					'{{WRAPPER}} .elementor-tab-title, {{WRAPPER}} .elementor-tab-title a' => 'color: {{VALUE}}',
    316 				],
    317 				'global' => [
    318 					'default' => Global_Colors::COLOR_PRIMARY,
    319 				],
    320 			]
    321 		);
    322 
    323 		$this->add_control(
    324 			'tab_active_color',
    325 			[
    326 				'label' => esc_html__( 'Active Color', 'elementor' ),
    327 				'type' => Controls_Manager::COLOR,
    328 				'selectors' => [
    329 					'{{WRAPPER}} .elementor-tab-title.elementor-active,
    330 					 {{WRAPPER}} .elementor-tab-title.elementor-active a' => 'color: {{VALUE}}',
    331 				],
    332 				'global' => [
    333 					'default' => Global_Colors::COLOR_ACCENT,
    334 				],
    335 			]
    336 		);
    337 
    338 		$this->add_group_control(
    339 			Group_Control_Typography::get_type(),
    340 			[
    341 				'name' => 'tab_typography',
    342 				'selector' => '{{WRAPPER}} .elementor-tab-title',
    343 				'global' => [
    344 					'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
    345 				],
    346 			]
    347 		);
    348 
    349 		$this->add_group_control(
    350 			Group_Control_Text_Shadow::get_type(),
    351 			[
    352 				'name' => 'title_shadow',
    353 				'selector' => '{{WRAPPER}} .elementor-tab-title',
    354 			]
    355 		);
    356 
    357 		$this->add_control(
    358 			'title_align',
    359 			[
    360 				'label' => esc_html__( 'Alignment', 'elementor' ),
    361 				'type' => Controls_Manager::CHOOSE,
    362 				'options' => [
    363 					'left' => [
    364 						'title' => esc_html__( 'Left', 'elementor' ),
    365 						'icon' => 'eicon-text-align-left',
    366 					],
    367 					'center' => [
    368 						'title' => esc_html__( 'Center', 'elementor' ),
    369 						'icon' => 'eicon-text-align-center',
    370 					],
    371 					'right' => [
    372 						'title' => esc_html__( 'Right', 'elementor' ),
    373 						'icon' => 'eicon-text-align-right',
    374 					],
    375 				],
    376 				'selectors' => [
    377 					'{{WRAPPER}} .elementor-tab-title' => 'text-align: {{VALUE}};',
    378 				],
    379 				'condition' => [
    380 					'tabs_align' => 'stretch',
    381 				],
    382 			]
    383 		);
    384 
    385 		$this->add_control(
    386 			'heading_content',
    387 			[
    388 				'label' => esc_html__( 'Content', 'elementor' ),
    389 				'type' => Controls_Manager::HEADING,
    390 				'separator' => 'before',
    391 			]
    392 		);
    393 
    394 		$this->add_control(
    395 			'content_color',
    396 			[
    397 				'label' => esc_html__( 'Color', 'elementor' ),
    398 				'type' => Controls_Manager::COLOR,
    399 				'selectors' => [
    400 					'{{WRAPPER}} .elementor-tab-content' => 'color: {{VALUE}};',
    401 				],
    402 				'global' => [
    403 					'default' => Global_Colors::COLOR_TEXT,
    404 				],
    405 			]
    406 		);
    407 
    408 		$this->add_group_control(
    409 			Group_Control_Typography::get_type(),
    410 			[
    411 				'name' => 'content_typography',
    412 				'selector' => '{{WRAPPER}} .elementor-tab-content',
    413 				'global' => [
    414 					'default' => Global_Typography::TYPOGRAPHY_TEXT,
    415 				],
    416 			]
    417 		);
    418 
    419 		$this->add_group_control(
    420 			Group_Control_Text_Shadow::get_type(),
    421 			[
    422 				'name' => 'content_shadow',
    423 				'selector' => '{{WRAPPER}} .elementor-tab-content',
    424 			]
    425 		);
    426 
    427 		$this->end_controls_section();
    428 	}
    429 
    430 	/**
    431 	 * Render tabs widget output on the frontend.
    432 	 *
    433 	 * Written in PHP and used to generate the final HTML.
    434 	 *
    435 	 * @since 1.0.0
    436 	 * @access protected
    437 	 */
    438 	protected function render() {
    439 		$tabs = $this->get_settings_for_display( 'tabs' );
    440 
    441 		$id_int = substr( $this->get_id_int(), 0, 3 );
    442 
    443 		$a11y_improvements_experiment = Plugin::$instance->experiments->is_feature_active( 'a11y_improvements' );
    444 
    445 		$this->add_render_attribute( 'elementor-tabs', 'class', 'elementor-tabs' );
    446 
    447 		?>
    448 		<div <?php $this->print_render_attribute_string( 'elementor-tabs' ); ?>>
    449 			<div class="elementor-tabs-wrapper" role="tablist" >
    450 				<?php
    451 				foreach ( $tabs as $index => $item ) :
    452 					$tab_count = $index + 1;
    453 					$tab_title_setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $index );
    454 					$tab_title = $a11y_improvements_experiment ? $item['tab_title'] : '<a href="">' . $item['tab_title'] . '</a>';
    455 
    456 					$this->add_render_attribute( $tab_title_setting_key, [
    457 						'id' => 'elementor-tab-title-' . $id_int . $tab_count,
    458 						'class' => [ 'elementor-tab-title', 'elementor-tab-desktop-title' ],
    459 						'aria-selected' => 1 === $tab_count ? 'true' : 'false',
    460 						'data-tab' => $tab_count,
    461 						'role' => 'tab',
    462 						'tabindex' => 1 === $tab_count ? '0' : '-1',
    463 						'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
    464 						'aria-expanded' => 'false',
    465 					] );
    466 					?>
    467 					<div <?php $this->print_render_attribute_string( $tab_title_setting_key ); ?>><?php
    468 						// PHPCS - the main text of a widget should not be escaped.
    469 						echo $tab_title; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    470 					?></div>
    471 				<?php endforeach; ?>
    472 			</div>
    473 			<div class="elementor-tabs-content-wrapper" role="tablist" aria-orientation="vertical">
    474 				<?php
    475 				foreach ( $tabs as $index => $item ) :
    476 					$tab_count = $index + 1;
    477 					$hidden = 1 === $tab_count ? 'false' : 'hidden';
    478 					$tab_content_setting_key = $this->get_repeater_setting_key( 'tab_content', 'tabs', $index );
    479 
    480 					$tab_title_mobile_setting_key = $this->get_repeater_setting_key( 'tab_title_mobile', 'tabs', $tab_count );
    481 
    482 					$this->add_render_attribute( $tab_content_setting_key, [
    483 						'id' => 'elementor-tab-content-' . $id_int . $tab_count,
    484 						'class' => [ 'elementor-tab-content', 'elementor-clearfix' ],
    485 						'data-tab' => $tab_count,
    486 						'role' => 'tabpanel',
    487 						'aria-labelledby' => 'elementor-tab-title-' . $id_int . $tab_count,
    488 						'tabindex' => '0',
    489 						'hidden' => $hidden,
    490 					] );
    491 
    492 					$this->add_render_attribute( $tab_title_mobile_setting_key, [
    493 						'class' => [ 'elementor-tab-title', 'elementor-tab-mobile-title' ],
    494 						'aria-selected' => 1 === $tab_count ? 'true' : 'false',
    495 						'data-tab' => $tab_count,
    496 						'role' => 'tab',
    497 						'tabindex' => 1 === $tab_count ? '0' : '-1',
    498 						'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
    499 						'aria-expanded' => 'false',
    500 					] );
    501 
    502 					$this->add_inline_editing_attributes( $tab_content_setting_key, 'advanced' );
    503 					?>
    504 					<div <?php $this->print_render_attribute_string( $tab_title_mobile_setting_key ); ?>><?php
    505 						$this->print_unescaped_setting( 'tab_title', 'tabs', $index );
    506 					?></div>
    507 					<div <?php $this->print_render_attribute_string( $tab_content_setting_key ); ?>><?php
    508 						$this->print_text_editor( $item['tab_content'] );
    509 					?></div>
    510 				<?php endforeach; ?>
    511 			</div>
    512 		</div>
    513 		<?php
    514 	}
    515 
    516 	/**
    517 	 * Render tabs widget output in the editor.
    518 	 *
    519 	 * Written as a Backbone JavaScript template and used to generate the live preview.
    520 	 *
    521 	 * @since 2.9.0
    522 	 * @access protected
    523 	 */
    524 	protected function content_template() {
    525 		?>
    526 		<div class="elementor-tabs" role="tablist" aria-orientation="vertical">
    527 			<# if ( settings.tabs ) {
    528 				var elementUid = view.getIDInt().toString().substr( 0, 3 ); #>
    529 				<div class="elementor-tabs-wrapper" role="tablist">
    530 					<# _.each( settings.tabs, function( item, index ) {
    531 						var tabCount = index + 1,
    532 							tabUid = elementUid + tabCount,
    533 							tabTitleKey = 'tab-title-' + tabUid;
    534 
    535 					view.addRenderAttribute( tabTitleKey, {
    536 						'id': 'elementor-tab-title-' + tabUid,
    537 						'class': [ 'elementor-tab-title','elementor-tab-desktop-title' ],
    538 						'data-tab': tabCount,
    539 						'role': 'tab',
    540 						'tabindex': 1 === tabCount ? '0' : '-1',
    541 						'aria-controls': 'elementor-tab-content-' + tabUid,
    542 						'aria-expanded': 'false',
    543 						} );
    544 					#>
    545 						<div {{{ view.getRenderAttributeString( tabTitleKey ) }}}>{{{ item.tab_title }}}</div>
    546 					<# } ); #>
    547 				</div>
    548 				<div class="elementor-tabs-content-wrapper">
    549 					<# _.each( settings.tabs, function( item, index ) {
    550 						var tabCount = index + 1,
    551 							tabContentKey = view.getRepeaterSettingKey( 'tab_content', 'tabs',index );
    552 
    553 						view.addRenderAttribute( tabContentKey, {
    554 							'id': 'elementor-tab-content-' + elementUid + tabCount,
    555 							'class': [ 'elementor-tab-content', 'elementor-clearfix', 'elementor-repeater-item-' + item._id ],
    556 							'data-tab': tabCount,
    557 							'role' : 'tabpanel',
    558 							'aria-labelledby' : 'elementor-tab-title-' + elementUid + tabCount
    559 						} );
    560 
    561 						view.addInlineEditingAttributes( tabContentKey, 'advanced' ); #>
    562 						<div class="elementor-tab-title elementor-tab-mobile-title" data-tab="{{ tabCount }}" role="tab">{{{ item.tab_title }}}</div>
    563 						<div {{{ view.getRenderAttributeString( tabContentKey ) }}}>{{{ item.tab_content }}}</div>
    564 					<# } ); #>
    565 				</div>
    566 			<# } #>
    567 		</div>
    568 		<?php
    569 	}
    570 }