PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.3
Elementor Website Builder – more than just a page builder v4.3.3
4.3.3 4.3.2 4.3.1 4.3.0 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 All 456 releases
elementor / modules / atomic-widgets / elements / atomic-tabs / atomic-tabs / atomic-tabs.php

atomic-tabs.php in Elementor Website Builder – more than just a page builder 4.3.3, at modules/atomic-widgets/elements/atomic-tabs/atomic-tabs/atomic-tabs.php

260 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Modules\AtomicWidgets\Elements\Atomic_Tabs\Atomic_Tabs;
3
4 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Paragraph\Atomic_Paragraph;
5 use Elementor\Modules\AtomicWidgets\Elements\Base\Atomic_Element_Base;
6 use Elementor\Modules\AtomicWidgets\Elements\Base\Has_Element_Template;
7 use Elementor\Modules\AtomicWidgets\Elements\Base\Html_Tag_Computer;
8 use Elementor\Modules\AtomicWidgets\PropTypes\Primitives\Number_Prop_Type;
9 use Elementor\Modules\AtomicWidgets\PropTypes\Primitives\String_Prop_Type;
10 use Elementor\Modules\AtomicWidgets\PropTypes\Size_Prop_Type;
11 use Elementor\Modules\AtomicWidgets\Styles\Style_Definition;
12 use Elementor\Modules\AtomicWidgets\Styles\Style_Variant;
13 use Elementor\Modules\AtomicWidgets\Controls\Section;
14 use Elementor\Modules\AtomicWidgets\Controls\Types\Text_Control;
15 use Elementor\Modules\AtomicWidgets\PropTypes\Classes_Prop_Type;
16 use Elementor\Modules\AtomicWidgets\PropTypes\Attributes_Prop_Type;
17 use Elementor\Modules\AtomicWidgets\PropTypes\Dimensions_Prop_Type;
18 use Elementor\Modules\AtomicWidgets\Controls\Types\Elements\Tabs_Control;
19 use Elementor\Modules\AtomicWidgets\Elements\Loader\Frontend_Assets_Loader;
20 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Tabs\Atomic_Tab\Atomic_Tab;
21 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Tabs\Atomic_Tab_Content\Atomic_Tab_Content;
22 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Tabs\Atomic_Tabs_Menu\Atomic_Tabs_Menu;
23 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Tabs\Atomic_Tabs_Content_Area\Atomic_Tabs_Content_Area;
24 use Elementor\Modules\Components\PropTypes\Overridable_Prop_Type;
25 use Elementor\Core\Utils\Collection;
26 use Elementor\Utils;
27 use Elementor\Plugin;
28
29 if ( ! defined( 'ABSPATH' ) ) {
30 exit; // Exit if accessed directly.
31 }
32
33 class Atomic_Tabs extends Atomic_Element_Base {
34 use Has_Element_Template;
35
36 const BASE_STYLE_KEY = 'base';
37 const ELEMENT_TYPE_TABS_MENU = 'e-tabs-menu';
38 const ELEMENT_TYPE_TABS_CONTENT_AREA = 'e-tabs-content-area';
39 const ELEMENT_TYPE_TAB = 'e-tab';
40 const ELEMENT_TYPE_TAB_CONTENT = 'e-tab-content';
41
42 public static $widget_description = 'Create a tabbed interface with customizable tabs and content areas. Structure: e-tabs contains e-tabs-menu (with e-tab triggers) and e-tabs-content-area (with e-tab-content panels). The number of e-tab elements MUST equal the number of e-tab-content elements. Each e-tab at index N is paired with the e-tab-content at index N.';
43
44 public function __construct( $data = [], $args = null ) {
45 parent::__construct( $data, $args );
46 $this->meta( 'is_container', true );
47 $this->meta( 'is_compound', true );
48 }
49
50 public static function get_type() {
51 return 'e-tabs';
52 }
53
54 public static function get_element_type(): string {
55 return 'e-tabs';
56 }
57
58 public function get_title() {
59 return esc_html__( 'Tabs', 'elementor' );
60 }
61
62 public function get_keywords() {
63 return [ 'ato', 'atom', 'atoms', 'atomic' ];
64 }
65
66 public function get_icon() {
67 return 'eicon-tabs';
68 }
69
70 public static function get_computed_html_tag( array $settings ): string {
71 return Html_Tag_Computer::compute( $settings, 'div' );
72 }
73
74 protected static function define_props_schema(): array {
75 return [
76 'classes' => Classes_Prop_Type::make()
77 ->default( [] ),
78 'default-active-tab' => Number_Prop_Type::make()
79 ->default( 0 )
80 ->meta( Overridable_Prop_Type::ignore() ),
81 'attributes' => Attributes_Prop_Type::make()->meta( Overridable_Prop_Type::ignore() ),
82 ];
83 }
84
85 protected function define_atomic_controls(): array {
86 return [
87 Section::make()
88 ->set_label( __( 'Content', 'elementor' ) )
89 ->set_id( 'content' )
90 ->set_items( [
91 Tabs_Control::make()
92 ->set_label( __( 'Menu items', 'elementor' ) )
93 ->set_meta( [
94 'layout' => 'custom',
95 ] ),
96 ] ),
97 Section::make()
98 ->set_label( __( 'Settings', 'elementor' ) )
99 ->set_id( 'settings' )
100 ->set_items( [
101 Text_Control::bind_to( '_cssid' )
102 ->set_label( __( 'ID', 'elementor' ) )
103 ->set_meta( [
104 'layout' => 'two-columns',
105 ] ),
106 ] ),
107 ];
108 }
109
110 protected function define_base_styles(): array {
111 $styles = [
112 'display' => String_Prop_Type::generate( 'flex' ),
113 'flex-direction' => String_Prop_Type::generate( 'column' ),
114 'gap' => Size_Prop_Type::generate( [
115 'size' => 30,
116 'unit' => 'px',
117 ]),
118 'padding' => Dimensions_Prop_Type::generate( [
119 'block-start' => Size_Prop_Type::generate( [
120 'size' => 0,
121 'unit' => 'px',
122 ]),
123 ] ),
124 ];
125
126 return [
127 static::BASE_STYLE_KEY => Style_Definition::make()
128 ->add_variant(
129 Style_Variant::make()
130 ->add_props( $styles )
131 ),
132 ];
133 }
134
135 protected function define_default_children() {
136 $default_tab_count = 3;
137 $tab_elements = [];
138 $tab_content_elements = [];
139
140 foreach ( range( 1, $default_tab_count ) as $i ) {
141 $tab_elements[] = Atomic_Tab::generate()
142 ->editor_settings( [
143 'title' => "Tab {$i} trigger",
144 'initial_position' => $i,
145 ] )
146 ->build();
147
148 $tab_content_elements[] = Atomic_Tab_Content::generate()
149 ->editor_settings( [
150 'title' => "Tab {$i} content",
151 'initial_position' => $i,
152 ] )
153 ->build();
154 }
155
156 $tabs_menu = Atomic_Tabs_Menu::generate()
157 ->children( $tab_elements )
158 ->build();
159
160 $tabs_content_area = Atomic_Tabs_Content_Area::generate()
161 ->children( $tab_content_elements )
162 ->build();
163
164 return [
165 $tabs_menu,
166 $tabs_content_area,
167 ];
168 }
169
170 public function get_script_depends() {
171 $global_depends = parent::get_script_depends();
172
173 if ( Plugin::$instance->preview->is_preview_mode() ) {
174 return array_merge( $global_depends, [ 'elementor-tabs-handler', 'elementor-tabs-preview-handler' ] );
175 }
176
177 return array_merge( $global_depends, [ 'elementor-tabs-handler' ] );
178 }
179
180 public function register_frontend_handlers() {
181 $assets_url = ELEMENTOR_ASSETS_URL;
182 $min_suffix = ( Utils::is_script_debug() || Utils::is_elementor_tests() ) ? '' : '.min';
183
184 wp_register_script(
185 'elementor-tabs-handler',
186 "{$assets_url}js/tabs-handler{$min_suffix}.js",
187 [ Frontend_Assets_Loader::FRONTEND_HANDLERS_HANDLE, Frontend_Assets_Loader::ALPINEJS_HANDLE ],
188 ELEMENTOR_VERSION,
189 true
190 );
191
192 wp_register_script(
193 'elementor-tabs-preview-handler',
194 "{$assets_url}js/tabs-preview-handler{$min_suffix}.js",
195 [ Frontend_Assets_Loader::FRONTEND_HANDLERS_HANDLE, Frontend_Assets_Loader::ALPINEJS_HANDLE ],
196 ELEMENTOR_VERSION,
197 true
198 );
199 }
200
201 private function get_filtered_children_ids( $parent_element, $child_type ) {
202 if ( ! $parent_element ) {
203 return [];
204 }
205
206 return Collection::make( $parent_element->get_children() )
207 ->filter( fn( $element ) => $element->get_type() === $child_type )
208 ->map( fn( $element ) => $element->get_id() )
209 ->flip()
210 ->all();
211 }
212
213 private function get_tab_index( $tab_id ) {
214 $direct_children = Collection::make( $this->get_children() );
215 $tabs_menu = $direct_children->filter( fn( $child ) => $child->get_type() === self::ELEMENT_TYPE_TABS_MENU )->first();
216
217 $tab_ids = $this->get_filtered_children_ids( $tabs_menu, self::ELEMENT_TYPE_TAB );
218
219 return $tab_ids[ $tab_id ];
220 }
221
222 private function get_tab_content_index( $tab_content_id ) {
223 $direct_children = Collection::make( $this->get_children() );
224 $tabs_content_area = $direct_children->filter( fn( $child ) => $child->get_type() === self::ELEMENT_TYPE_TABS_CONTENT_AREA )->first();
225
226 $tab_content_ids = $this->get_filtered_children_ids( $tabs_content_area, self::ELEMENT_TYPE_TAB_CONTENT );
227
228 return $tab_content_ids[ $tab_content_id ];
229 }
230
231 protected function define_render_context(): array {
232 $default_active_tab = $this->get_atomic_setting( 'default-active-tab' );
233
234 return [
235 [
236 'context' => [
237 'default-active-tab' => $default_active_tab,
238 'get-tab-index' => fn( $tab_id ) => $this->get_tab_index( $tab_id ),
239 'get-tab-content-index' => fn( $tab_content_id ) => $this->get_tab_content_index( $tab_content_id ),
240 'tabs-id' => $this->get_id(),
241 ],
242 ],
243 ];
244 }
245
246 protected function get_templates(): array {
247 return [
248 'elementor/elements/atomic-tabs' => __DIR__ . '/atomic-tabs.html.twig',
249 ];
250 }
251
252 public static function get_tab_id( $tabs_id, $index ) {
253 return "{$tabs_id}-tab-{$index}";
254 }
255
256 public static function get_tab_content_id( $tabs_id, $index ) {
257 return "{$tabs_id}-tab-content-{$index}";
258 }
259 }
260