PluginProbe
Elementor Website Builder – more than just a page builder / 3.22.1
Elementor Website Builder – more than just a page builder v3.22.1
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 4.0.7 All 451 releases
elementor / includes / elements / column.php

column.php in Elementor Website Builder – more than just a page builder 3.22.1, at includes/elements/column.php

1,061 lines 26.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor;
3
4 use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit; // Exit if accessed directly.
8 }
9
10 /**
11 * Elementor column element.
12 *
13 * Elementor column handler class is responsible for initializing the column
14 * element.
15 *
16 * @since 1.0.0
17 */
18 class Element_Column extends Element_Base {
19
20 /**
21 * Get column name.
22 *
23 * Retrieve the column name.
24 *
25 * @since 1.0.0
26 * @access public
27 *
28 * @return string Column name.
29 */
30 public function get_name() {
31 return 'column';
32 }
33
34 /**
35 * Get element type.
36 *
37 * Retrieve the element type, in this case `column`.
38 *
39 * @since 2.1.0
40 * @access public
41 * @static
42 *
43 * @return string The type.
44 */
45 public static function get_type() {
46 return 'column';
47 }
48
49 /**
50 * Get column title.
51 *
52 * Retrieve the column title.
53 *
54 * @since 1.0.0
55 * @access public
56 *
57 * @return string Column title.
58 */
59 public function get_title() {
60 return esc_html__( 'Column', 'elementor' );
61 }
62
63 /**
64 * Get column icon.
65 *
66 * Retrieve the column icon.
67 *
68 * @since 1.0.0
69 * @access public
70 *
71 * @return string Column icon.
72 */
73 public function get_icon() {
74 return 'eicon-column';
75 }
76
77 protected function is_dynamic_content(): bool {
78 return false;
79 }
80
81 /**
82 * Get initial config.
83 *
84 * Retrieve the current section initial configuration.
85 *
86 * Adds more configuration on top of the controls list, the tabs assigned to
87 * the control, element name, type, icon and more. This method also adds
88 * section presets.
89 *
90 * @since 2.9.0
91 * @access protected
92 *
93 * @return array The initial config.
94 */
95 protected function get_initial_config() {
96 $config = parent::get_initial_config();
97
98 $config['controls'] = $this->get_controls();
99 $config['tabs_controls'] = $this->get_tabs_controls();
100
101 return $config;
102 }
103
104 /**
105 * Register column controls.
106 *
107 * Used to add new controls to the column element.
108 *
109 * @since 3.1.0
110 * @access protected
111 */
112 protected function register_controls() {
113 // Section Layout.
114 $this->start_controls_section(
115 'layout',
116 [
117 'label' => esc_html__( 'Layout', 'elementor' ),
118 'tab' => Controls_Manager::TAB_LAYOUT,
119 ]
120 );
121
122 // Element Name for the Navigator
123 $this->add_control(
124 '_title',
125 [
126 'label' => esc_html__( 'Title', 'elementor' ),
127 'type' => Controls_Manager::HIDDEN,
128 'render_type' => 'none',
129 ]
130 );
131
132 $active_breakpoint_keys = array_reverse( array_keys( Plugin::$instance->breakpoints->get_active_breakpoints() ) );
133 $inline_size_device_args = [
134 Breakpoints_Manager::BREAKPOINT_KEY_MOBILE => [ 'placeholder' => 100 ],
135 ];
136
137 foreach ( $active_breakpoint_keys as $breakpoint_key ) {
138 if ( ! isset( $inline_size_device_args[ $breakpoint_key ] ) ) {
139 $inline_size_device_args[ $breakpoint_key ] = [];
140 }
141
142 $inline_size_device_args[ $breakpoint_key ] = array_merge_recursive(
143 $inline_size_device_args[ $breakpoint_key ],
144 [
145 'max' => 100,
146 'required' => false,
147 ]
148 );
149 }
150
151 if ( in_array( Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA, $active_breakpoint_keys, true ) ) {
152 $min_affected_device_value = Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA;
153 } else {
154 $min_affected_device_value = Breakpoints_Manager::BREAKPOINT_KEY_TABLET;
155 }
156
157 $this->add_responsive_control(
158 '_inline_size',
159 [
160 'label' => esc_html__( 'Column Width', 'elementor' ) . ' (%)',
161 'type' => Controls_Manager::NUMBER,
162 'min' => 2,
163 'max' => 98,
164 'required' => true,
165 'device_args' => $inline_size_device_args,
166 'min_affected_device' => [
167 Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP => $min_affected_device_value,
168 Breakpoints_Manager::BREAKPOINT_KEY_LAPTOP => $min_affected_device_value,
169 Breakpoints_Manager::BREAKPOINT_KEY_TABLET_EXTRA => $min_affected_device_value,
170 Breakpoints_Manager::BREAKPOINT_KEY_TABLET => $min_affected_device_value,
171 Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA => $min_affected_device_value,
172 ],
173 'selectors' => [
174 '{{WRAPPER}}' => 'width: {{VALUE}}%',
175 ],
176 ]
177 );
178
179 $this->add_responsive_control(
180 'content_position',
181 [
182 'label' => esc_html__( 'Vertical Alignment', 'elementor' ),
183 'type' => Controls_Manager::SELECT,
184 'default' => '',
185 'options' => [
186 '' => esc_html__( 'Default', 'elementor' ),
187 'top' => esc_html__( 'Top', 'elementor' ),
188 'center' => esc_html__( 'Middle', 'elementor' ),
189 'bottom' => esc_html__( 'Bottom', 'elementor' ),
190 'space-between' => esc_html__( 'Space Between', 'elementor' ),
191 'space-around' => esc_html__( 'Space Around', 'elementor' ),
192 'space-evenly' => esc_html__( 'Space Evenly', 'elementor' ),
193 ],
194 'selectors_dictionary' => [
195 'top' => 'flex-start',
196 'bottom' => 'flex-end',
197 ],
198 'selectors' => [
199 // TODO: The following line is for BC since 2.7.0
200 '.elementor-bc-flex-widget {{WRAPPER}}.elementor-column .elementor-widget-wrap' => 'align-items: {{VALUE}}',
201 // This specificity is intended to make sure column css overwrites section css on vertical alignment (content_position)
202 '{{WRAPPER}}.elementor-column.elementor-element[data-element_type="column"] > .elementor-widget-wrap.elementor-element-populated' => 'align-content: {{VALUE}}; align-items: {{VALUE}};',
203 ],
204 ]
205 );
206
207 $this->add_responsive_control(
208 'align',
209 [
210 'label' => esc_html__( 'Horizontal Alignment', 'elementor' ),
211 'type' => Controls_Manager::SELECT,
212 'default' => '',
213 'options' => [
214 '' => esc_html__( 'Default', 'elementor' ),
215 'flex-start' => esc_html__( 'Start', 'elementor' ),
216 'center' => esc_html__( 'Center', 'elementor' ),
217 'flex-end' => esc_html__( 'End', 'elementor' ),
218 'space-between' => esc_html__( 'Space Between', 'elementor' ),
219 'space-around' => esc_html__( 'Space Around', 'elementor' ),
220 'space-evenly' => esc_html__( 'Space Evenly', 'elementor' ),
221 ],
222 'selectors' => [
223 '{{WRAPPER}}.elementor-column > .elementor-widget-wrap' => 'justify-content: {{VALUE}}',
224 ],
225 ]
226 );
227
228 $this->add_responsive_control(
229 'space_between_widgets',
230 [
231 'label' => esc_html__( 'Widgets Space', 'elementor' ) . ' (px)',
232 'type' => Controls_Manager::NUMBER,
233 'placeholder' => 20,
234 'selectors' => [
235 '{{WRAPPER}} > .elementor-widget-wrap > .elementor-widget:not(.elementor-widget__width-auto):not(.elementor-widget__width-initial):not(:last-child):not(.elementor-absolute)' => 'margin-bottom: {{VALUE}}px', //Need the full path for exclude the inner section
236 ],
237 ]
238 );
239
240 $possible_tags = [
241 'div',
242 'header',
243 'footer',
244 'main',
245 'article',
246 'section',
247 'aside',
248 'nav',
249 ];
250
251 $options = [
252 '' => esc_html__( 'Default', 'elementor' ),
253 ] + array_combine( $possible_tags, $possible_tags );
254
255 $this->add_control(
256 'html_tag',
257 [
258 'label' => esc_html__( 'HTML Tag', 'elementor' ),
259 'type' => Controls_Manager::SELECT,
260 'options' => $options,
261 'render_type' => 'none',
262 ]
263 );
264
265 $this->end_controls_section();
266
267 $this->start_controls_section(
268 'section_style',
269 [
270 'label' => esc_html__( 'Background', 'elementor' ),
271 'tab' => Controls_Manager::TAB_STYLE,
272 ]
273 );
274
275 $this->start_controls_tabs( 'tabs_background' );
276
277 $this->start_controls_tab(
278 'tab_background_normal',
279 [
280 'label' => esc_html__( 'Normal', 'elementor' ),
281 ]
282 );
283
284 $this->add_group_control(
285 Group_Control_Background::get_type(),
286 [
287 'name' => 'background',
288 'types' => [ 'classic', 'gradient', 'slideshow' ],
289 'selector' => '{{WRAPPER}}:not(.elementor-motion-effects-element-type-background) > .elementor-widget-wrap, {{WRAPPER}} > .elementor-widget-wrap > .elementor-motion-effects-container > .elementor-motion-effects-layer',
290 'fields_options' => [
291 'background' => [
292 'frontend_available' => true,
293 ],
294 ],
295 ]
296 );
297
298 $this->end_controls_tab();
299
300 $this->start_controls_tab(
301 'tab_background_hover',
302 [
303 'label' => esc_html__( 'Hover', 'elementor' ),
304 ]
305 );
306
307 $this->add_group_control(
308 Group_Control_Background::get_type(),
309 [
310 'name' => 'background_hover',
311 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated',
312 ]
313 );
314
315 $this->add_control(
316 'background_hover_transition',
317 [
318 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
319 'type' => Controls_Manager::SLIDER,
320 'default' => [
321 'size' => 0.3,
322 ],
323 'range' => [
324 'px' => [
325 'min' => 0,
326 'max' => 3,
327 'step' => 0.1,
328 ],
329 ],
330 'render_type' => 'ui',
331 'separator' => 'before',
332 ]
333 );
334
335 $this->end_controls_tab();
336
337 $this->end_controls_tabs();
338
339 $this->end_controls_section();
340
341 // Section Column Background Overlay.
342 $this->start_controls_section(
343 'section_background_overlay',
344 [
345 'label' => esc_html__( 'Background Overlay', 'elementor' ),
346 'tab' => Controls_Manager::TAB_STYLE,
347 'condition' => [
348 'background_background' => [ 'classic', 'gradient' ],
349 ],
350 ]
351 );
352
353 $this->start_controls_tabs( 'tabs_background_overlay' );
354
355 $this->start_controls_tab(
356 'tab_background_overlay_normal',
357 [
358 'label' => esc_html__( 'Normal', 'elementor' ),
359 ]
360 );
361
362 $this->add_group_control(
363 Group_Control_Background::get_type(),
364 [
365 'name' => 'background_overlay',
366 'selector' => '{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay',
367 ]
368 );
369
370 $this->add_responsive_control(
371 'background_overlay_opacity',
372 [
373 'label' => esc_html__( 'Opacity', 'elementor' ),
374 'type' => Controls_Manager::SLIDER,
375 'default' => [
376 'size' => .5,
377 ],
378 'range' => [
379 'px' => [
380 'max' => 1,
381 'step' => 0.01,
382 ],
383 ],
384 'selectors' => [
385 '{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay' => 'opacity: {{SIZE}};',
386 ],
387 'condition' => [
388 'background_overlay_background' => [ 'classic', 'gradient' ],
389 ],
390 ]
391 );
392
393 $this->add_group_control(
394 Group_Control_Css_Filter::get_type(),
395 [
396 'name' => 'css_filters',
397 'selector' => '{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay',
398 ]
399 );
400
401 $this->add_control(
402 'overlay_blend_mode',
403 [
404 'label' => esc_html__( 'Blend Mode', 'elementor' ),
405 'type' => Controls_Manager::SELECT,
406 'options' => [
407 '' => esc_html__( 'Normal', 'elementor' ),
408 'multiply' => esc_html__( 'Multiply', 'elementor' ),
409 'screen' => esc_html__( 'Screen', 'elementor' ),
410 'overlay' => esc_html__( 'Overlay', 'elementor' ),
411 'darken' => esc_html__( 'Darken', 'elementor' ),
412 'lighten' => esc_html__( 'Lighten', 'elementor' ),
413 'color-dodge' => esc_html__( 'Color Dodge', 'elementor' ),
414 'saturation' => esc_html__( 'Saturation', 'elementor' ),
415 'color' => esc_html__( 'Color', 'elementor' ),
416 'difference' => esc_html__( 'Difference', 'elementor' ),
417 'exclusion' => esc_html__( 'Exclusion', 'elementor' ),
418 'hue' => esc_html__( 'Hue', 'elementor' ),
419 'luminosity' => esc_html__( 'Luminosity', 'elementor' ),
420 ],
421 'selectors' => [
422 '{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay' => 'mix-blend-mode: {{VALUE}}',
423 ],
424 ]
425 );
426
427 $this->end_controls_tab();
428
429 $this->start_controls_tab(
430 'tab_background_overlay_hover',
431 [
432 'label' => esc_html__( 'Hover', 'elementor' ),
433 ]
434 );
435
436 $this->add_group_control(
437 Group_Control_Background::get_type(),
438 [
439 'name' => 'background_overlay_hover',
440 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated > .elementor-background-overlay',
441 ]
442 );
443
444 $this->add_responsive_control(
445 'background_overlay_hover_opacity',
446 [
447 'label' => esc_html__( 'Opacity', 'elementor' ),
448 'type' => Controls_Manager::SLIDER,
449 'default' => [
450 'size' => .5,
451 ],
452 'range' => [
453 'px' => [
454 'max' => 1,
455 'step' => 0.01,
456 ],
457 ],
458 'selectors' => [
459 '{{WRAPPER}}:hover > .elementor-element-populated > .elementor-background-overlay' => 'opacity: {{SIZE}};',
460 ],
461 'condition' => [
462 'background_overlay_hover_background' => [ 'classic', 'gradient' ],
463 ],
464 ]
465 );
466
467 $this->add_group_control(
468 Group_Control_Css_Filter::get_type(),
469 [
470 'name' => 'css_filters_hover',
471 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated > .elementor-background-overlay',
472 ]
473 );
474
475 $this->add_control(
476 'background_overlay_hover_transition',
477 [
478 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
479 'type' => Controls_Manager::SLIDER,
480 'default' => [
481 'size' => 0.3,
482 ],
483 'range' => [
484 'px' => [
485 'min' => 0,
486 'max' => 3,
487 'step' => 0.1,
488 ],
489 ],
490 'render_type' => 'ui',
491 'separator' => 'before',
492 ]
493 );
494
495 $this->end_controls_tab();
496
497 $this->end_controls_tabs();
498
499 $this->end_controls_section();
500
501 $this->start_controls_section(
502 'section_border',
503 [
504 'label' => esc_html__( 'Border', 'elementor' ),
505 'tab' => Controls_Manager::TAB_STYLE,
506 ]
507 );
508
509 $this->start_controls_tabs( 'tabs_border' );
510
511 $this->start_controls_tab(
512 'tab_border_normal',
513 [
514 'label' => esc_html__( 'Normal', 'elementor' ),
515 ]
516 );
517
518 $this->add_group_control(
519 Group_Control_Border::get_type(),
520 [
521 'name' => 'border',
522 'selector' => '{{WRAPPER}} > .elementor-element-populated',
523 ]
524 );
525
526 $this->add_responsive_control(
527 'border_radius',
528 [
529 'label' => esc_html__( 'Border Radius', 'elementor' ),
530 'type' => Controls_Manager::DIMENSIONS,
531 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
532 'selectors' => [
533 '{{WRAPPER}} > .elementor-element-populated, {{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay, {{WRAPPER}} > .elementor-background-slideshow' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
534 ],
535 ]
536 );
537
538 $this->add_group_control(
539 Group_Control_Box_Shadow::get_type(),
540 [
541 'name' => 'box_shadow',
542 'selector' => '{{WRAPPER}} > .elementor-element-populated',
543 ]
544 );
545
546 $this->end_controls_tab();
547
548 $this->start_controls_tab(
549 'tab_border_hover',
550 [
551 'label' => esc_html__( 'Hover', 'elementor' ),
552 ]
553 );
554
555 $this->add_group_control(
556 Group_Control_Border::get_type(),
557 [
558 'name' => 'border_hover',
559 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated',
560 ]
561 );
562
563 $this->add_responsive_control(
564 'border_radius_hover',
565 [
566 'label' => esc_html__( 'Border Radius', 'elementor' ),
567 'type' => Controls_Manager::DIMENSIONS,
568 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
569 'selectors' => [
570 '{{WRAPPER}}:hover > .elementor-element-populated, {{WRAPPER}}:hover > .elementor-element-populated > .elementor-background-overlay' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
571 ],
572 ]
573 );
574
575 $this->add_group_control(
576 Group_Control_Box_Shadow::get_type(),
577 [
578 'name' => 'box_shadow_hover',
579 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated',
580 ]
581 );
582
583 $this->add_control(
584 'border_hover_transition',
585 [
586 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
587 'type' => Controls_Manager::SLIDER,
588 'separator' => 'before',
589 'default' => [
590 'size' => 0.3,
591 ],
592 'range' => [
593 'px' => [
594 'min' => 0,
595 'max' => 3,
596 'step' => 0.1,
597 ],
598 ],
599 'conditions' => [
600 'relation' => 'or',
601 'terms' => [
602 [
603 'name' => 'background_background',
604 'operator' => '!==',
605 'value' => '',
606 ],
607 [
608 'name' => 'border_border',
609 'operator' => '!==',
610 'value' => '',
611 ],
612 ],
613 ],
614 'selectors' => [
615 '{{WRAPPER}} > .elementor-element-populated' => 'transition: background {{background_hover_transition.SIZE}}s, border {{SIZE}}s, border-radius {{SIZE}}s, box-shadow {{SIZE}}s',
616 '{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay' => 'transition: background {{background_overlay_hover_transition.SIZE}}s, border-radius {{SIZE}}s, opacity {{background_overlay_hover_transition.SIZE}}s',
617 ],
618 ]
619 );
620
621 $this->end_controls_tab();
622
623 $this->end_controls_tabs();
624
625 $this->end_controls_section();
626
627 // Section Typography.
628 $this->start_controls_section(
629 'section_typo',
630 [
631 'label' => esc_html__( 'Typography', 'elementor' ),
632 'type' => Controls_Manager::SECTION,
633 'tab' => Controls_Manager::TAB_STYLE,
634 ]
635 );
636
637 $this->add_control(
638 'heading_color',
639 [
640 'label' => esc_html__( 'Heading Color', 'elementor' ),
641 'type' => Controls_Manager::COLOR,
642 'default' => '',
643 'selectors' => [
644 '{{WRAPPER}} .elementor-element-populated .elementor-heading-title' => 'color: {{VALUE}};',
645 ],
646 ]
647 );
648
649 $this->add_control(
650 'color_text',
651 [
652 'label' => esc_html__( 'Text Color', 'elementor' ),
653 'type' => Controls_Manager::COLOR,
654 'default' => '',
655 'selectors' => [
656 '{{WRAPPER}} > .elementor-element-populated' => 'color: {{VALUE}};',
657 ],
658 ]
659 );
660
661 $this->add_control(
662 'color_link',
663 [
664 'label' => esc_html__( 'Link Color', 'elementor' ),
665 'type' => Controls_Manager::COLOR,
666 'default' => '',
667 'selectors' => [
668 '{{WRAPPER}} .elementor-element-populated a' => 'color: {{VALUE}};',
669 ],
670 ]
671 );
672
673 $this->add_control(
674 'color_link_hover',
675 [
676 'label' => esc_html__( 'Link Hover Color', 'elementor' ),
677 'type' => Controls_Manager::COLOR,
678 'default' => '',
679 'selectors' => [
680 '{{WRAPPER}} .elementor-element-populated a:hover' => 'color: {{VALUE}};',
681 ],
682 ]
683 );
684
685 $this->add_responsive_control(
686 'text_align',
687 [
688 'label' => esc_html__( 'Text Align', 'elementor' ),
689 'type' => Controls_Manager::CHOOSE,
690 'options' => [
691 'left' => [
692 'title' => esc_html__( 'Left', 'elementor' ),
693 'icon' => 'eicon-text-align-left',
694 ],
695 'center' => [
696 'title' => esc_html__( 'Center', 'elementor' ),
697 'icon' => 'eicon-text-align-center',
698 ],
699 'right' => [
700 'title' => esc_html__( 'Right', 'elementor' ),
701 'icon' => 'eicon-text-align-right',
702 ],
703 'justify' => [
704 'title' => esc_html__( 'Justified', 'elementor' ),
705 'icon' => 'eicon-text-align-justify',
706 ],
707 ],
708 'selectors' => [
709 '{{WRAPPER}} > .elementor-element-populated' => 'text-align: {{VALUE}};',
710 ],
711 ]
712 );
713
714 $this->end_controls_section();
715
716 // Section Advanced.
717 $this->start_controls_section(
718 'section_advanced',
719 [
720 'label' => esc_html__( 'Advanced', 'elementor' ),
721 'type' => Controls_Manager::SECTION,
722 'tab' => Controls_Manager::TAB_ADVANCED,
723 ]
724 );
725
726 $this->add_responsive_control(
727 'margin',
728 [
729 'label' => esc_html__( 'Margin', 'elementor' ),
730 'type' => Controls_Manager::DIMENSIONS,
731 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
732 'selectors' => [
733 '{{WRAPPER}} > .elementor-element-populated' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};
734 --e-column-margin-right: {{RIGHT}}{{UNIT}}; --e-column-margin-left: {{LEFT}}{{UNIT}};',
735 ],
736 ]
737 );
738
739 $this->add_responsive_control(
740 'padding',
741 [
742 'label' => esc_html__( 'Padding', 'elementor' ),
743 'type' => Controls_Manager::DIMENSIONS,
744 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
745 'selectors' => [
746 '{{WRAPPER}} > .elementor-element-populated' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
747 ],
748 ]
749 );
750
751 $this->add_responsive_control(
752 'z_index',
753 [
754 'label' => esc_html__( 'Z-Index', 'elementor' ),
755 'type' => Controls_Manager::NUMBER,
756 'min' => 0,
757 'selectors' => [
758 '{{WRAPPER}}' => 'z-index: {{VALUE}};',
759 ],
760 ]
761 );
762
763 $this->add_control(
764 '_element_id',
765 [
766 'label' => esc_html__( 'CSS ID', 'elementor' ),
767 'type' => Controls_Manager::TEXT,
768 'default' => '',
769 'ai' => [
770 'active' => false,
771 ],
772 'dynamic' => [
773 'active' => true,
774 ],
775 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
776 'style_transfer' => false,
777 'classes' => 'elementor-control-direction-ltr',
778 ]
779 );
780
781 $this->add_control(
782 'css_classes',
783 [
784 'label' => esc_html__( 'CSS Classes', 'elementor' ),
785 'type' => Controls_Manager::TEXT,
786 'default' => '',
787 'ai' => [
788 'active' => false,
789 ],
790 'dynamic' => [
791 'active' => true,
792 ],
793 'prefix_class' => '',
794 'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor' ),
795 'classes' => 'elementor-control-direction-ltr',
796 ]
797 );
798
799 Plugin::$instance->controls_manager->add_display_conditions_controls( $this );
800
801 // TODO: Backward comparability for deprecated controls
802 $this->add_control(
803 'screen_sm',
804 [
805 'type' => Controls_Manager::HIDDEN,
806 ]
807 );
808
809 $this->add_control(
810 'screen_sm_width',
811 [
812 'type' => Controls_Manager::HIDDEN,
813 'condition' => [
814 'screen_sm' => [ 'custom' ],
815 ],
816 'prefix_class' => 'elementor-sm-',
817 ]
818 );
819 // END Backward comparability
820
821 $this->end_controls_section();
822
823 $this->start_controls_section(
824 'section_effects',
825 [
826 'label' => esc_html__( 'Motion Effects', 'elementor' ),
827 'tab' => Controls_Manager::TAB_ADVANCED,
828 ]
829 );
830
831 Plugin::$instance->controls_manager->add_motion_effects_promotion_control( $this );
832
833 $this->add_responsive_control(
834 'animation',
835 [
836 'label' => esc_html__( 'Entrance Animation', 'elementor' ),
837 'type' => Controls_Manager::ANIMATION,
838 'frontend_available' => true,
839 ]
840 );
841
842 $this->add_control(
843 'animation_duration',
844 [
845 'label' => esc_html__( 'Animation Duration', 'elementor' ),
846 'type' => Controls_Manager::SELECT,
847 'default' => '',
848 'options' => [
849 'slow' => esc_html__( 'Slow', 'elementor' ),
850 '' => esc_html__( 'Normal', 'elementor' ),
851 'fast' => esc_html__( 'Fast', 'elementor' ),
852 ],
853 'prefix_class' => 'animated-',
854 'condition' => [
855 'animation!' => '',
856 ],
857 ]
858 );
859
860 $this->add_control(
861 'animation_delay',
862 [
863 'label' => esc_html__( 'Animation Delay', 'elementor' ) . ' (ms)',
864 'type' => Controls_Manager::NUMBER,
865 'default' => '',
866 'min' => 0,
867 'step' => 100,
868 'condition' => [
869 'animation!' => '',
870 ],
871 'render_type' => 'none',
872 'frontend_available' => true,
873 ]
874 );
875
876 $this->end_controls_section();
877
878 $this->start_controls_section(
879 '_section_responsive',
880 [
881 'label' => esc_html__( 'Responsive', 'elementor' ),
882 'tab' => Controls_Manager::TAB_ADVANCED,
883 ]
884 );
885
886 $this->add_control(
887 'responsive_description',
888 [
889 'raw' => sprintf(
890 /* translators: 1: Link open tag, 2: Link close tag. */
891 esc_html__( 'Responsive visibility will take effect only on %1$s preview mode %2$s or live page, and not while editing in Elementor.', 'elementor' ),
892 '<a href="javascript: $e.run( \'panel/close\' )">',
893 '</a>'
894 ),
895 'type' => Controls_Manager::RAW_HTML,
896 'content_classes' => 'elementor-descriptor',
897 ]
898 );
899
900 $this->add_hidden_device_controls();
901
902 $this->end_controls_section();
903
904 Plugin::$instance->controls_manager->add_custom_attributes_controls( $this );
905
906 Plugin::$instance->controls_manager->add_custom_css_controls( $this );
907 }
908
909 /**
910 * Render column output in the editor.
911 *
912 * Used to generate the live preview, using a Backbone JavaScript template.
913 *
914 * @since 2.9.0
915 * @access protected
916 */
917 protected function content_template() {
918 ?>
919 <div class="elementor-widget-wrap">
920 <div class="elementor-background-overlay"></div>
921 </div>
922 <?php
923 }
924
925 /**
926 * Before column rendering.
927 *
928 * Used to add stuff before the column element.
929 *
930 * @since 1.0.0
931 * @access public
932 */
933 public function before_render() {
934 $settings = $this->get_settings_for_display();
935
936 $overlay_background = $settings['background_overlay_background'] ?? '';
937 $overlay_hover_background = $settings['background_overlay_hover_background'] ?? '';
938
939 $has_background_overlay = in_array( $overlay_background, [ 'classic', 'gradient' ], true ) ||
940 in_array( $overlay_hover_background, [ 'classic', 'gradient' ], true );
941
942 $column_wrap_classes = [ 'elementor-widget-wrap' ];
943
944 if ( $this->get_children() ) {
945 $column_wrap_classes[] = 'elementor-element-populated';
946 }
947
948 $this->add_render_attribute( [
949 '_widget_wrapper' => [
950 'class' => $column_wrap_classes,
951 ],
952 '_background_overlay' => [
953 'class' => [ 'elementor-background-overlay' ],
954 ],
955 ] );
956 ?>
957 <<?php
958 // PHPCS - the method get_html_tag is safe.
959 echo $this->get_html_tag(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
960 ?> <?php $this->print_render_attribute_string( '_wrapper' ); ?>>
961 <div <?php $this->print_render_attribute_string( '_widget_wrapper' ); ?>>
962 <?php if ( $has_background_overlay ) : ?>
963 <div <?php $this->print_render_attribute_string( '_background_overlay' ); ?>></div>
964 <?php endif; ?>
965 <?php
966 }
967
968 /**
969 * After column rendering.
970 *
971 * Used to add stuff after the column element.
972 *
973 * @since 1.0.0
974 * @access public
975 */
976 public function after_render() {
977 ?>
978 </div>
979 </<?php
980 // PHPCS - the method get_html_tag is safe.
981 echo $this->get_html_tag(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
982 <?php
983 }
984
985 /**
986 * Add column render attributes.
987 *
988 * Used to add attributes to the current column wrapper HTML tag.
989 *
990 * @since 1.3.0
991 * @access protected
992 */
993 protected function add_render_attributes() {
994
995 $is_inner = $this->get_data( 'isInner' );
996
997 $column_type = ! empty( $is_inner ) ? 'inner' : 'top';
998
999 $settings = $this->get_settings();
1000
1001 $this->add_render_attribute(
1002 '_wrapper', 'class', [
1003 'elementor-column',
1004 'elementor-col-' . $settings['_column_size'],
1005 'elementor-' . $column_type . '-column',
1006 ]
1007 );
1008
1009 parent::add_render_attributes();
1010 }
1011
1012 /**
1013 * Get default child type.
1014 *
1015 * Retrieve the column child type based on element data.
1016 *
1017 * @since 1.0.0
1018 * @access protected
1019 *
1020 * @param array $element_data Element ID.
1021 *
1022 * @return Element_Base|false Column default child type.
1023 */
1024 protected function _get_default_child_type( array $element_data ) {
1025 if ( 'section' === $element_data['elType'] ) {
1026 return Plugin::$instance->elements_manager->get_element_types( 'section' );
1027 }
1028
1029 if ( 'container' === $element_data['elType'] ) {
1030 return Plugin::$instance->elements_manager->get_element_types( 'container' );
1031 }
1032
1033 // If the element doesn't exists (disabled element, experiment, etc.), return false to prevent errors.
1034 if ( empty( $element_data['widgetType'] ) ) {
1035 return false;
1036 }
1037
1038 return Plugin::$instance->widgets_manager->get_widget_types( $element_data['widgetType'] );
1039 }
1040
1041 /**
1042 * Get HTML tag.
1043 *
1044 * Retrieve the column element HTML tag.
1045 *
1046 * @since 1.5.3
1047 * @access private
1048 *
1049 * @return string Column HTML tag.
1050 */
1051 private function get_html_tag() {
1052 $html_tag = $this->get_settings( 'html_tag' );
1053
1054 if ( empty( $html_tag ) ) {
1055 $html_tag = 'div';
1056 }
1057
1058 return Utils::validate_html_tag( $html_tag );
1059 }
1060 }
1061