PluginProbe
Elementor Website Builder – more than just a page builder / 3.20.0-dev3
Elementor Website Builder – more than just a page builder v3.20.0-dev3
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.20.0-dev3, at includes/elements/column.php

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