PluginProbe
Elementor Website Builder – more than just a page builder / 4.0.0-dev4
Elementor Website Builder – more than just a page builder v4.0.0-dev4
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 4.1.0-dev2 All 455 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.0.0-dev4, at modules/atomic-widgets/elements/atomic-tabs/atomic-tabs/atomic-tabs.php

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