← All changes
|
modules/nested-tabs/widgets/nested-tabs.php
+58
-56
4.1.0-dev2
→
3.23.0-dev3
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 | } |
| @@ -41,29 +39,13 @@ | ||
| 41 | 39 | public function get_keywords() { |
| 42 | 40 | return [ 'nested', 'tabs', 'accordion', 'toggle' ]; |
| 43 | 41 | } |
| 44 | 42 | |
| 45 | - public function get_style_depends(): array { | |
| 46 | - return [ 'widget-nested-tabs' ]; | |
| 47 | - } | |
| 48 | - | |
| 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 | 43 | protected function tab_content_container( int $index ) { |
| 58 | 44 | return [ |
| 59 | 45 | 'elType' => 'container', |
| 60 | 46 | 'settings' => [ |
| 61 | - '_title' => sprintf( | |
| 62 | - /* translators: %d: Tab index. */ | |
| 63 | - __( 'Tab #%d', 'elementor' ), | |
| 64 | - $index | |
| 65 | - ), | |
| 47 | + '_title' => sprintf( __( 'Tab #%s', 'elementor' ), $index ), | |
| 66 | 48 | 'content_width' => 'full', |
| 67 | 49 | ], |
| 68 | 50 | ]; |
| 69 | 51 | } |
| @@ -80,9 +62,8 @@ | ||
| 80 | 62 | return 'tab_title'; |
| 81 | 63 | } |
| 82 | 64 | |
| 83 | 65 | protected function get_default_children_title() { |
| 84 | - /* translators: %d: Tab index. */ | |
| 85 | 66 | return esc_html__( 'Tab #%d', 'elementor' ); |
| 86 | 67 | } |
| 87 | 68 | |
| 88 | 69 | protected function get_default_children_placeholder_selector() { |
| @@ -93,21 +74,16 @@ | ||
| 93 | 74 | return 'elementor-widget-n-tabs'; |
| 94 | 75 | } |
| 95 | 76 | |
| 96 | 77 | 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 | 78 | $start = is_rtl() ? 'right' : 'left'; |
| 103 | 79 | $end = is_rtl() ? 'left' : 'right'; |
| 104 | 80 | $start_logical = is_rtl() ? 'end' : 'start'; |
| 105 | 81 | $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"; | |
| 82 | + $heading_selector_non_touch_device = '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs[data-touch-mode="false"] > .e-n-tabs-heading'; | |
| 83 | + $heading_selector_touch_device = '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs[data-touch-mode="true"] > .e-n-tabs-heading'; | |
| 84 | + $heading_selector = '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs > .e-n-tabs-heading'; | |
| 85 | + $content_selector = ':where( {{WRAPPER}} > .elementor-widget-container > .e-n-tabs > .e-n-tabs-content ) > .e-con'; | |
| 110 | 86 | |
| 111 | 87 | $this->start_controls_section( 'section_tabs', [ |
| 112 | 88 | 'label' => esc_html__( 'Tabs', 'elementor' ), |
| 113 | 89 | ] ); |
| @@ -183,9 +159,9 @@ | ||
| 183 | 159 | 'tab_title' => esc_html__( 'Tab #3', 'elementor' ), |
| 184 | 160 | ], |
| 185 | 161 | ], |
| 186 | 162 | 'title_field' => '{{{ tab_title }}}', |
| 187 | - 'button_text' => esc_html__( 'Add Tab', 'elementor' ), | |
| 163 | + 'button_text' => 'Add Tab', | |
| 188 | 164 | ] ); |
| 189 | 165 | |
| 190 | 166 | $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 | 167 | $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 +480,9 @@ | ||
| 504 | 480 | [ |
| 505 | 481 | 'name' => 'tabs_title_background_color', |
| 506 | 482 | 'types' => [ 'classic', 'gradient' ], |
| 507 | 483 | '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 )", | |
| 484 | + 'selector' => '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="false"]:not( :hover )', | |
| 509 | 485 | 'fields_options' => [ |
| 510 | 486 | 'color' => [ |
| 511 | 487 | 'label' => esc_html__( 'Background Color', 'elementor' ), |
| 512 | 488 | 'selectors' => [ |
| @@ -536,8 +512,9 @@ | ||
| 536 | 512 | $this->add_group_control( |
| 537 | 513 | Group_Control_Box_Shadow::get_type(), |
| 538 | 514 | [ |
| 539 | 515 | 'name' => 'tabs_title_box_shadow', |
| 516 | + 'label' => esc_html__( 'Shadow', 'elementor' ), | |
| 540 | 517 | 'separator' => 'after', |
| 541 | 518 | 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )", |
| 542 | 519 | ] |
| 543 | 520 | ); |
| @@ -594,8 +571,9 @@ | ||
| 594 | 571 | $this->add_group_control( |
| 595 | 572 | Group_Control_Box_Shadow::get_type(), |
| 596 | 573 | [ |
| 597 | 574 | 'name' => 'tabs_title_box_shadow_hover', |
| 575 | + 'label' => esc_html__( 'Shadow', 'elementor' ), | |
| 598 | 576 | 'separator' => 'after', |
| 599 | 577 | 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover", |
| 600 | 578 | ] |
| 601 | 579 | ); |
| @@ -678,8 +656,9 @@ | ||
| 678 | 656 | $this->add_group_control( |
| 679 | 657 | Group_Control_Box_Shadow::get_type(), |
| 680 | 658 | [ |
| 681 | 659 | 'name' => 'tabs_title_box_shadow_active', |
| 660 | + 'label' => esc_html__( 'Shadow', 'elementor' ), | |
| 682 | 661 | 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover", |
| 683 | 662 | ] |
| 684 | 663 | ); |
| 685 | 664 | |
| @@ -758,8 +737,13 @@ | ||
| 758 | 737 | Group_Control_Text_Shadow::get_type(), |
| 759 | 738 | [ |
| 760 | 739 | 'name' => 'title_text_shadow', |
| 761 | 740 | 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )", |
| 741 | + 'fields_options' => [ | |
| 742 | + 'text_shadow_type' => [ | |
| 743 | + 'label' => esc_html__( 'Shadow', 'elementor' ), | |
| 744 | + ], | |
| 745 | + ], | |
| 762 | 746 | ] |
| 763 | 747 | ); |
| 764 | 748 | |
| 765 | 749 | $this->add_group_control( |
| @@ -766,8 +750,13 @@ | ||
| 766 | 750 | Group_Control_Text_Stroke::get_type(), |
| 767 | 751 | [ |
| 768 | 752 | 'name' => 'title_text_stroke', |
| 769 | 753 | 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover ) :is( span, a, i )", |
| 754 | + 'fields_options' => [ | |
| 755 | + 'text_stroke_type' => [ | |
| 756 | + 'label' => esc_html__( 'Stroke', 'elementor' ), | |
| 757 | + ], | |
| 758 | + ], | |
| 770 | 759 | ] |
| 771 | 760 | ); |
| 772 | 761 | |
| 773 | 762 | $this->end_controls_tab(); |
| @@ -794,8 +783,14 @@ | ||
| 794 | 783 | Group_Control_Text_Shadow::get_type(), |
| 795 | 784 | [ |
| 796 | 785 | 'name' => 'title_text_shadow_hover', |
| 797 | 786 | 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover", |
| 787 | + 'fields_options' => [ | |
| 788 | + 'text_shadow_type' => [ | |
| 789 | + 'label' => esc_html__( 'Shadow', 'elementor' ), | |
| 790 | + ], | |
| 791 | + ], | |
| 792 | + | |
| 798 | 793 | ] |
| 799 | 794 | ); |
| 800 | 795 | |
| 801 | 796 | $this->add_group_control( |
| @@ -802,8 +797,13 @@ | ||
| 802 | 797 | Group_Control_Text_Stroke::get_type(), |
| 803 | 798 | [ |
| 804 | 799 | 'name' => 'title_text_stroke_hover', |
| 805 | 800 | 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover :is( span, a, i )", |
| 801 | + 'fields_options' => [ | |
| 802 | + 'text_stroke_type' => [ | |
| 803 | + 'label' => esc_html__( 'Stroke', 'elementor' ), | |
| 804 | + ], | |
| 805 | + ], | |
| 806 | 806 | ] |
| 807 | 807 | ); |
| 808 | 808 | |
| 809 | 809 | $this->end_controls_tab(); |
| @@ -830,8 +830,13 @@ | ||
| 830 | 830 | Group_Control_Text_Shadow::get_type(), |
| 831 | 831 | [ |
| 832 | 832 | 'name' => 'title_text_shadow_active', |
| 833 | 833 | 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover", |
| 834 | + 'fields_options' => [ | |
| 835 | + 'text_shadow_type' => [ | |
| 836 | + 'label' => esc_html__( 'Shadow', 'elementor' ), | |
| 837 | + ], | |
| 838 | + ], | |
| 834 | 839 | ] |
| 835 | 840 | ); |
| 836 | 841 | |
| 837 | 842 | $this->add_group_control( |
| @@ -838,8 +843,13 @@ | ||
| 838 | 843 | Group_Control_Text_Stroke::get_type(), |
| 839 | 844 | [ |
| 840 | 845 | 'name' => 'title_text_stroke_active', |
| 841 | 846 | '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 )", |
| 847 | + 'fields_options' => [ | |
| 848 | + 'text_stroke_type' => [ | |
| 849 | + 'label' => esc_html__( 'Stroke', 'elementor' ), | |
| 850 | + ], | |
| 851 | + ], | |
| 842 | 852 | ] |
| 843 | 853 | ); |
| 844 | 854 | |
| 845 | 855 | $this->end_controls_tab(); |
| @@ -1075,9 +1085,8 @@ | ||
| 1075 | 1085 | } |
| 1076 | 1086 | |
| 1077 | 1087 | $this->add_render_attribute( $setting_key, [ |
| 1078 | 1088 | 'id' => $item_settings['tab_id'], |
| 1079 | - 'data-tab-title-id' => $item_settings['tab_title_id'], | |
| 1080 | 1089 | 'class' => $css_classes, |
| 1081 | 1090 | 'aria-selected' => 1 === $item_settings['tab_count'] ? 'true' : 'false', |
| 1082 | 1091 | 'data-tab-index' => $item_settings['tab_count'], |
| 1083 | 1092 | 'role' => 'tab', |
| @@ -1123,9 +1132,9 @@ | ||
| 1123 | 1132 | |
| 1124 | 1133 | /** |
| 1125 | 1134 | * Print the content area. |
| 1126 | 1135 | * |
| 1127 | - * @param int $index | |
| 1136 | + * @param int $index | |
| 1128 | 1137 | * @param array $item_settings |
| 1129 | 1138 | */ |
| 1130 | 1139 | public function print_child( $index, $item_settings = [] ) { |
| 1131 | 1140 | $children = $this->get_children(); |
| @@ -1184,11 +1193,11 @@ | ||
| 1184 | 1193 | <div class="e-n-tabs-heading" role="tablist"> |
| 1185 | 1194 | <?php |
| 1186 | 1195 | foreach ( $settings['tabs'] as $index => $item ) { |
| 1187 | 1196 | $tab_count = $index + 1; |
| 1188 | - $tab_title_id = 'e-n-tab-title-' . $widget_number . $tab_count; | |
| 1197 | + | |
| 1189 | 1198 | $tab_id = empty( $item['element_id'] ) |
| 1190 | - ? $tab_title_id | |
| 1199 | + ? 'e-n-tab-title-' . $widget_number . $tab_count | |
| 1191 | 1200 | : $item['element_id']; |
| 1192 | 1201 | |
| 1193 | 1202 | $item_settings = [ |
| 1194 | 1203 | 'index' => $index, |
| @@ -1193,9 +1202,8 @@ | ||
| 1193 | 1202 | $item_settings = [ |
| 1194 | 1203 | 'index' => $index, |
| 1195 | 1204 | 'tab_count' => $tab_count, |
| 1196 | 1205 | 'tab_id' => $tab_id, |
| 1197 | - 'tab_title_id' => $tab_title_id, | |
| 1198 | 1206 | 'container_id' => 'e-n-tab-content-' . $widget_number . $tab_count, |
| 1199 | 1207 | 'widget_number' => $widget_number, |
| 1200 | 1208 | 'item' => $item, |
| 1201 | 1209 | 'settings' => $settings, |
| @@ -1214,13 +1222,17 @@ | ||
| 1214 | 1222 | <?php |
| 1215 | 1223 | } |
| 1216 | 1224 | |
| 1217 | 1225 | 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 | - ] ); | |
| 1226 | + if ( Plugin::$instance->experiments->is_feature_active( 'e_nested_atomic_repeaters' ) ) { | |
| 1227 | + return array_merge( parent::get_initial_config(), [ | |
| 1228 | + 'support_improved_repeaters' => true, | |
| 1229 | + 'target_container' => [ '.e-n-tabs-heading' ], | |
| 1230 | + 'node' => 'button', | |
| 1231 | + ] ); | |
| 1232 | + } | |
| 1233 | + | |
| 1234 | + return parent::get_initial_config(); | |
| 1223 | 1235 | } |
| 1224 | 1236 | |
| 1225 | 1237 | protected function content_template_single_repeater_item() { |
| 1226 | 1238 | ?> |
| @@ -1261,12 +1273,11 @@ | ||
| 1261 | 1273 | private function content_template_single_item( $tab_index, $item, $element_uid, $hover_animation_class ) { |
| 1262 | 1274 | ?> |
| 1263 | 1275 | <# |
| 1264 | 1276 | const tabCount = tabIndex + 1, |
| 1265 | - tabTitleId = 'e-n-tab-title-' + elementUid + tabCount, | |
| 1266 | 1277 | tabId = item.element_id |
| 1267 | 1278 | ? item.element_id |
| 1268 | - : tabTitleId, | |
| 1279 | + : 'e-n-tab-title-' + elementUid + ( tabIndex + 1 ), | |
| 1269 | 1280 | tabUid = elementUid + tabCount, |
| 1270 | 1281 | tabIcon = elementor.helpers.renderIcon( view, item.tab_icon, { 'aria-hidden': true }, 'i' , 'object' ), |
| 1271 | 1282 | activeTabIcon = item.tab_icon_active.value |
| 1272 | 1283 | ? elementor.helpers.renderIcon( view, item.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' ) |
| @@ -1274,9 +1285,8 @@ | ||
| 1274 | 1285 | escapedHoverAnimationClass = _.escape( hoverAnimationClass ); |
| 1275 | 1286 | |
| 1276 | 1287 | view.addRenderAttribute( 'tab-title', { |
| 1277 | 1288 | 'id': tabId, |
| 1278 | - 'data-tab-title-id': tabTitleId, | |
| 1279 | 1289 | 'class': [ 'e-n-tab-title',escapedHoverAnimationClass ], |
| 1280 | 1290 | 'data-tab-index': tabCount, |
| 1281 | 1291 | 'role': 'tab', |
| 1282 | 1292 | 'aria-selected': 1 === tabCount ? 'true' : 'false', |
| @@ -1288,20 +1298,11 @@ | ||
| 1288 | 1298 | view.addRenderAttribute( 'tab-title-text', { |
| 1289 | 1299 | 'class': [ 'e-n-tab-title-text' ], |
| 1290 | 1300 | 'data-binding-type': 'repeater-item', |
| 1291 | 1301 | 'data-binding-repeater-name': 'tabs', |
| 1292 | - 'data-binding-setting': [ 'tab_title', 'element_id' ], | |
| 1302 | + 'data-binding-setting': [ 'tab_title' ], | |
| 1293 | 1303 | '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 | - }), | |
| 1304 | + 'data-binding-dynamic': 'true', | |
| 1304 | 1305 | }, null, true ); |
| 1305 | 1306 | |
| 1306 | 1307 | view.addRenderAttribute( 'tab-icon', { |
| 1307 | 1308 | 'class': [ 'e-n-tab-icon' ], |
| @@ -1306,8 +1307,9 @@ | ||
| 1306 | 1307 | view.addRenderAttribute( 'tab-icon', { |
| 1307 | 1308 | 'class': [ 'e-n-tab-icon' ], |
| 1308 | 1309 | 'data-binding-type': 'repeater-item', |
| 1309 | 1310 | 'data-binding-repeater-name': 'tabs', |
| 1311 | + 'data-binding-setting': [ 'tab_icon', 'tab_icon_active' ], | |
| 1310 | 1312 | 'data-binding-index': tabCount, |
| 1311 | 1313 | }, null, true ); |
| 1312 | 1314 | #> |
| 1313 | 1315 | |