PluginProbe
Elementor Website Builder – more than just a page builder / 3.24.8
Elementor Website Builder – more than just a page builder v3.24.8
4.3.0-beta3 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 All 452 releases
← All changes | modules/nested-tabs/widgets/nested-tabs.php +58 -52 4.2.0-dev23.24.8 View file →
@@ -16,16 +16,14 @@
16 16 use Elementor\Plugin;
17 17 use Elementor\Repeater;
18 18
19 19 if ( ! defined( 'ABSPATH' ) ) {
20 - exit; // Exit if accessed directly.
20 + exit; // Exit if accessed directly
21 21 }
22 22
23 23 class NestedTabs extends Widget_Nested_Base {
24 24
25 25 private $tab_item_settings = [];
26 - private $optimized_markup = null;
27 - private $widget_container_selector = '';
28 26
29 27 public function get_name() {
30 28 return 'nested-tabs';
31 29 }
@@ -45,25 +43,13 @@
45 43 public function get_style_depends(): array {
46 44 return [ 'widget-nested-tabs' ];
47 45 }
48 46
49 - public function has_widget_inner_wrapper(): bool {
50 - return ! Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
51 - }
52 -
53 - public function show_in_panel(): bool {
54 - return Plugin::$instance->experiments->is_feature_active( 'nested-elements', true );
55 - }
56 -
57 47 protected function tab_content_container( int $index ) {
58 48 return [
59 49 'elType' => 'container',
60 50 'settings' => [
61 - '_title' => sprintf(
62 - /* translators: %d: Tab index. */
63 - __( 'Tab #%d', 'elementor' ),
64 - $index
65 - ),
51 + '_title' => sprintf( __( 'Tab #%s', 'elementor' ), $index ),
66 52 'content_width' => 'full',
67 53 ],
68 54 ];
69 55 }
@@ -80,9 +66,8 @@
80 66 return 'tab_title';
81 67 }
82 68
83 69 protected function get_default_children_title() {
84 - /* translators: %d: Tab index. */
85 70 return esc_html__( 'Tab #%d', 'elementor' );
86 71 }
87 72
88 73 protected function get_default_children_placeholder_selector() {
@@ -93,21 +78,16 @@
93 78 return 'elementor-widget-n-tabs';
94 79 }
95 80
96 81 protected function register_controls() {
97 - if ( null === $this->optimized_markup ) {
98 - $this->optimized_markup = Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' ) && ! $this->has_widget_inner_wrapper();
99 - $this->widget_container_selector = $this->optimized_markup ? '' : ' > .elementor-widget-container';
100 - }
101 -
102 82 $start = is_rtl() ? 'right' : 'left';
103 83 $end = is_rtl() ? 'left' : 'right';
104 84 $start_logical = is_rtl() ? 'end' : 'start';
105 85 $end_logical = is_rtl() ? 'start' : 'end';
106 - $heading_selector_non_touch_device = "{{WRAPPER}}.elementor-widget-n-tabs{$this->widget_container_selector} > .e-n-tabs[data-touch-mode='false'] > .e-n-tabs-heading";
107 - $heading_selector_touch_device = "{{WRAPPER}}.elementor-widget-n-tabs{$this->widget_container_selector} > .e-n-tabs[data-touch-mode='true'] > .e-n-tabs-heading";
108 - $heading_selector = "{{WRAPPER}}.elementor-widget-n-tabs{$this->widget_container_selector} > .e-n-tabs > .e-n-tabs-heading";
109 - $content_selector = ":where( {{WRAPPER}}.elementor-widget-n-tabs{$this->widget_container_selector} > .e-n-tabs > .e-n-tabs-content ) > .e-con";
86 + $heading_selector_non_touch_device = '{{WRAPPER}}.elementor-widget-n-tabs > .elementor-widget-container > .e-n-tabs[data-touch-mode="false"] > .e-n-tabs-heading';
87 + $heading_selector_touch_device = '{{WRAPPER}}.elementor-widget-n-tabs > .elementor-widget-container > .e-n-tabs[data-touch-mode="true"] > .e-n-tabs-heading';
88 + $heading_selector = '{{WRAPPER}}.elementor-widget-n-tabs > .elementor-widget-container > .e-n-tabs > .e-n-tabs-heading';
89 + $content_selector = ':where( {{WRAPPER}}.elementor-widget-n-tabs > .elementor-widget-container > .e-n-tabs > .e-n-tabs-content ) > .e-con';
110 90
111 91 $this->start_controls_section( 'section_tabs', [
112 92 'label' => esc_html__( 'Tabs', 'elementor' ),
113 93 ] );
@@ -183,9 +163,9 @@
183 163 'tab_title' => esc_html__( 'Tab #3', 'elementor' ),
184 164 ],
185 165 ],
186 166 'title_field' => '{{{ tab_title }}}',
187 - 'button_text' => esc_html__( 'Add Tab', 'elementor' ),
167 + 'button_text' => 'Add Tab',
188 168 ] );
189 169
190 170 $styling_block_start = '--n-tabs-direction: column; --n-tabs-heading-direction: row; --n-tabs-heading-width: initial; --n-tabs-title-flex-basis: content; --n-tabs-title-flex-shrink: 0;';
191 171 $styling_block_end = '--n-tabs-direction: column-reverse; --n-tabs-heading-direction: row; --n-tabs-heading-width: initial; --n-tabs-title-flex-basis: content; --n-tabs-title-flex-shrink: 0';
@@ -504,9 +484,9 @@
504 484 [
505 485 'name' => 'tabs_title_background_color',
506 486 'types' => [ 'classic', 'gradient' ],
507 487 'exclude' => [ 'image' ],
508 - 'selector' => "{{WRAPPER}}{$this->widget_container_selector} > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected='false']:not( :hover )",
488 + 'selector' => '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="false"]:not( :hover )',
509 489 'fields_options' => [
510 490 'color' => [
511 491 'label' => esc_html__( 'Background Color', 'elementor' ),
512 492 'selectors' => [
@@ -536,8 +516,9 @@
536 516 $this->add_group_control(
537 517 Group_Control_Box_Shadow::get_type(),
538 518 [
539 519 'name' => 'tabs_title_box_shadow',
520 + 'label' => esc_html__( 'Shadow', 'elementor' ),
540 521 'separator' => 'after',
541 522 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
542 523 ]
543 524 );
@@ -594,8 +575,9 @@
594 575 $this->add_group_control(
595 576 Group_Control_Box_Shadow::get_type(),
596 577 [
597 578 'name' => 'tabs_title_box_shadow_hover',
579 + 'label' => esc_html__( 'Shadow', 'elementor' ),
598 580 'separator' => 'after',
599 581 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
600 582 ]
601 583 );
@@ -678,8 +660,9 @@
678 660 $this->add_group_control(
679 661 Group_Control_Box_Shadow::get_type(),
680 662 [
681 663 'name' => 'tabs_title_box_shadow_active',
664 + 'label' => esc_html__( 'Shadow', 'elementor' ),
682 665 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
683 666 ]
684 667 );
685 668
@@ -758,8 +741,13 @@
758 741 Group_Control_Text_Shadow::get_type(),
759 742 [
760 743 'name' => 'title_text_shadow',
761 744 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
745 + 'fields_options' => [
746 + 'text_shadow_type' => [
747 + 'label' => esc_html__( 'Shadow', 'elementor' ),
748 + ],
749 + ],
762 750 ]
763 751 );
764 752
765 753 $this->add_group_control(
@@ -766,8 +754,13 @@
766 754 Group_Control_Text_Stroke::get_type(),
767 755 [
768 756 'name' => 'title_text_stroke',
769 757 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover ) :is( span, a, i )",
758 + 'fields_options' => [
759 + 'text_stroke_type' => [
760 + 'label' => esc_html__( 'Stroke', 'elementor' ),
761 + ],
762 + ],
770 763 ]
771 764 );
772 765
773 766 $this->end_controls_tab();
@@ -794,8 +787,14 @@
794 787 Group_Control_Text_Shadow::get_type(),
795 788 [
796 789 'name' => 'title_text_shadow_hover',
797 790 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
791 + 'fields_options' => [
792 + 'text_shadow_type' => [
793 + 'label' => esc_html__( 'Shadow', 'elementor' ),
794 + ],
795 + ],
796 +
798 797 ]
799 798 );
800 799
801 800 $this->add_group_control(
@@ -802,8 +801,13 @@
802 801 Group_Control_Text_Stroke::get_type(),
803 802 [
804 803 'name' => 'title_text_stroke_hover',
805 804 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover :is( span, a, i )",
805 + 'fields_options' => [
806 + 'text_stroke_type' => [
807 + 'label' => esc_html__( 'Stroke', 'elementor' ),
808 + ],
809 + ],
806 810 ]
807 811 );
808 812
809 813 $this->end_controls_tab();
@@ -830,8 +834,13 @@
830 834 Group_Control_Text_Shadow::get_type(),
831 835 [
832 836 'name' => 'title_text_shadow_active',
833 837 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
838 + 'fields_options' => [
839 + 'text_shadow_type' => [
840 + 'label' => esc_html__( 'Shadow', 'elementor' ),
841 + ],
842 + ],
834 843 ]
835 844 );
836 845
837 846 $this->add_group_control(
@@ -838,8 +847,13 @@
838 847 Group_Control_Text_Stroke::get_type(),
839 848 [
840 849 'name' => 'title_text_stroke_active',
841 850 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"] :is( span, a, i ), {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover :is( span, a, i )",
851 + 'fields_options' => [
852 + 'text_stroke_type' => [
853 + 'label' => esc_html__( 'Stroke', 'elementor' ),
854 + ],
855 + ],
842 856 ]
843 857 );
844 858
845 859 $this->end_controls_tab();
@@ -1075,9 +1089,8 @@
1075 1089 }
1076 1090
1077 1091 $this->add_render_attribute( $setting_key, [
1078 1092 'id' => $item_settings['tab_id'],
1079 - 'data-tab-title-id' => $item_settings['tab_title_id'],
1080 1093 'class' => $css_classes,
1081 1094 'aria-selected' => 1 === $item_settings['tab_count'] ? 'true' : 'false',
1082 1095 'data-tab-index' => $item_settings['tab_count'],
1083 1096 'role' => 'tab',
@@ -1123,9 +1136,9 @@
1123 1136
1124 1137 /**
1125 1138 * Print the content area.
1126 1139 *
1127 - * @param int $index
1140 + * @param int $index
1128 1141 * @param array $item_settings
1129 1142 */
1130 1143 public function print_child( $index, $item_settings = [] ) {
1131 1144 $children = $this->get_children();
@@ -1184,11 +1197,11 @@
1184 1197 <div class="e-n-tabs-heading" role="tablist">
1185 1198 <?php
1186 1199 foreach ( $settings['tabs'] as $index => $item ) {
1187 1200 $tab_count = $index + 1;
1188 - $tab_title_id = 'e-n-tab-title-' . $widget_number . $tab_count;
1201 +
1189 1202 $tab_id = empty( $item['element_id'] )
1190 - ? $tab_title_id
1203 + ? 'e-n-tab-title-' . $widget_number . $tab_count
1191 1204 : $item['element_id'];
1192 1205
1193 1206 $item_settings = [
1194 1207 'index' => $index,
@@ -1193,9 +1206,8 @@
1193 1206 $item_settings = [
1194 1207 'index' => $index,
1195 1208 'tab_count' => $tab_count,
1196 1209 'tab_id' => $tab_id,
1197 - 'tab_title_id' => $tab_title_id,
1198 1210 'container_id' => 'e-n-tab-content-' . $widget_number . $tab_count,
1199 1211 'widget_number' => $widget_number,
1200 1212 'item' => $item,
1201 1213 'settings' => $settings,
@@ -1214,13 +1226,17 @@
1214 1226 <?php
1215 1227 }
1216 1228
1217 1229 protected function get_initial_config(): array {
1218 - return array_merge( parent::get_initial_config(), [
1219 - 'support_improved_repeaters' => true,
1220 - 'target_container' => [ '.e-n-tabs-heading' ],
1221 - 'node' => 'button',
1222 - ] );
1230 + if ( Plugin::$instance->experiments->is_feature_active( 'e_nested_atomic_repeaters' ) ) {
1231 + return array_merge( parent::get_initial_config(), [
1232 + 'support_improved_repeaters' => true,
1233 + 'target_container' => [ '.e-n-tabs-heading' ],
1234 + 'node' => 'button',
1235 + ] );
1236 + }
1237 +
1238 + return parent::get_initial_config();
1223 1239 }
1224 1240
1225 1241 protected function content_template_single_repeater_item() {
1226 1242 ?>
@@ -1261,12 +1277,11 @@
1261 1277 private function content_template_single_item( $tab_index, $item, $element_uid, $hover_animation_class ) {
1262 1278 ?>
1263 1279 <#
1264 1280 const tabCount = tabIndex + 1,
1265 - tabTitleId = 'e-n-tab-title-' + elementUid + tabCount,
1266 1281 tabId = item.element_id
1267 1282 ? item.element_id
1268 - : tabTitleId,
1283 + : 'e-n-tab-title-' + elementUid + ( tabIndex + 1 ),
1269 1284 tabUid = elementUid + tabCount,
1270 1285 tabIcon = elementor.helpers.renderIcon( view, item.tab_icon, { 'aria-hidden': true }, 'i' , 'object' ),
1271 1286 activeTabIcon = item.tab_icon_active.value
1272 1287 ? elementor.helpers.renderIcon( view, item.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' )
@@ -1274,9 +1289,8 @@
1274 1289 escapedHoverAnimationClass = _.escape( hoverAnimationClass );
1275 1290
1276 1291 view.addRenderAttribute( 'tab-title', {
1277 1292 'id': tabId,
1278 - 'data-tab-title-id': tabTitleId,
1279 1293 'class': [ 'e-n-tab-title',escapedHoverAnimationClass ],
1280 1294 'data-tab-index': tabCount,
1281 1295 'role': 'tab',
1282 1296 'aria-selected': 1 === tabCount ? 'true' : 'false',
@@ -1288,20 +1302,11 @@
1288 1302 view.addRenderAttribute( 'tab-title-text', {
1289 1303 'class': [ 'e-n-tab-title-text' ],
1290 1304 'data-binding-type': 'repeater-item',
1291 1305 'data-binding-repeater-name': 'tabs',
1292 - 'data-binding-setting': [ 'tab_title', 'element_id' ],
1306 + 'data-binding-setting': [ 'tab_title' ],
1293 1307 'data-binding-index': tabCount,
1294 - 'data-binding-config': JSON.stringify({
1295 - 'element_id': {
1296 - attr: 'id',
1297 - selector: 'button',
1298 - editType: 'attribute',
1299 - },
1300 - 'tab_title': {
1301 - editType: 'text',
1302 - },
1303 - }),
1308 + 'data-binding-dynamic': 'true',
1304 1309 }, null, true );
1305 1310
1306 1311 view.addRenderAttribute( 'tab-icon', {
1307 1312 'class': [ 'e-n-tab-icon' ],
@@ -1306,8 +1311,9 @@
1306 1311 view.addRenderAttribute( 'tab-icon', {
1307 1312 'class': [ 'e-n-tab-icon' ],
1308 1313 'data-binding-type': 'repeater-item',
1309 1314 'data-binding-repeater-name': 'tabs',
1315 + 'data-binding-setting': [ 'tab_icon', 'tab_icon_active' ],
1310 1316 'data-binding-index': tabCount,
1311 1317 }, null, true );
1312 1318 #>
1313 1319