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

1,098 lines 27.3 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->add_control(
299 'handle_slideshow_asset_loading',
300 [
301 'type' => Controls_Manager::HIDDEN,
302 'assets' => [
303 'styles' => [
304 [
305 'name' => 'e-swiper',
306 'conditions' => [
307 'terms' => [
308 [
309 'name' => 'background_background',
310 'operator' => '===',
311 'value' => 'slideshow',
312 ],
313 ],
314 ],
315 ],
316 ],
317 'scripts' => [
318 [
319 'name' => 'swiper',
320 'conditions' => [
321 'terms' => [
322 [
323 'name' => 'background_background',
324 'operator' => '===',
325 'value' => 'slideshow',
326 ],
327 ],
328 ],
329 ],
330 ],
331 ],
332 ]
333 );
334
335 $this->end_controls_tab();
336
337 $this->start_controls_tab(
338 'tab_background_hover',
339 [
340 'label' => esc_html__( 'Hover', 'elementor' ),
341 ]
342 );
343
344 $this->add_group_control(
345 Group_Control_Background::get_type(),
346 [
347 'name' => 'background_hover',
348 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated',
349 ]
350 );
351
352 $this->add_control(
353 'background_hover_transition',
354 [
355 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
356 'type' => Controls_Manager::SLIDER,
357 'default' => [
358 'size' => 0.3,
359 ],
360 'range' => [
361 'px' => [
362 'min' => 0,
363 'max' => 3,
364 'step' => 0.1,
365 ],
366 ],
367 'render_type' => 'ui',
368 'separator' => 'before',
369 ]
370 );
371
372 $this->end_controls_tab();
373
374 $this->end_controls_tabs();
375
376 $this->end_controls_section();
377
378 // Section Column Background Overlay.
379 $this->start_controls_section(
380 'section_background_overlay',
381 [
382 'label' => esc_html__( 'Background Overlay', 'elementor' ),
383 'tab' => Controls_Manager::TAB_STYLE,
384 'condition' => [
385 'background_background' => [ 'classic', 'gradient' ],
386 ],
387 ]
388 );
389
390 $this->start_controls_tabs( 'tabs_background_overlay' );
391
392 $this->start_controls_tab(
393 'tab_background_overlay_normal',
394 [
395 'label' => esc_html__( 'Normal', 'elementor' ),
396 ]
397 );
398
399 $this->add_group_control(
400 Group_Control_Background::get_type(),
401 [
402 'name' => 'background_overlay',
403 'selector' => '{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay',
404 ]
405 );
406
407 $this->add_responsive_control(
408 'background_overlay_opacity',
409 [
410 'label' => esc_html__( 'Opacity', 'elementor' ),
411 'type' => Controls_Manager::SLIDER,
412 'default' => [
413 'size' => .5,
414 ],
415 'range' => [
416 'px' => [
417 'max' => 1,
418 'step' => 0.01,
419 ],
420 ],
421 'selectors' => [
422 '{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay' => 'opacity: {{SIZE}};',
423 ],
424 'condition' => [
425 'background_overlay_background' => [ 'classic', 'gradient' ],
426 ],
427 ]
428 );
429
430 $this->add_group_control(
431 Group_Control_Css_Filter::get_type(),
432 [
433 'name' => 'css_filters',
434 'selector' => '{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay',
435 ]
436 );
437
438 $this->add_control(
439 'overlay_blend_mode',
440 [
441 'label' => esc_html__( 'Blend Mode', 'elementor' ),
442 'type' => Controls_Manager::SELECT,
443 'options' => [
444 '' => esc_html__( 'Normal', 'elementor' ),
445 'multiply' => esc_html__( 'Multiply', 'elementor' ),
446 'screen' => esc_html__( 'Screen', 'elementor' ),
447 'overlay' => esc_html__( 'Overlay', 'elementor' ),
448 'darken' => esc_html__( 'Darken', 'elementor' ),
449 'lighten' => esc_html__( 'Lighten', 'elementor' ),
450 'color-dodge' => esc_html__( 'Color Dodge', 'elementor' ),
451 'saturation' => esc_html__( 'Saturation', 'elementor' ),
452 'color' => esc_html__( 'Color', 'elementor' ),
453 'difference' => esc_html__( 'Difference', 'elementor' ),
454 'exclusion' => esc_html__( 'Exclusion', 'elementor' ),
455 'hue' => esc_html__( 'Hue', 'elementor' ),
456 'luminosity' => esc_html__( 'Luminosity', 'elementor' ),
457 ],
458 'selectors' => [
459 '{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay' => 'mix-blend-mode: {{VALUE}}',
460 ],
461 ]
462 );
463
464 $this->end_controls_tab();
465
466 $this->start_controls_tab(
467 'tab_background_overlay_hover',
468 [
469 'label' => esc_html__( 'Hover', 'elementor' ),
470 ]
471 );
472
473 $this->add_group_control(
474 Group_Control_Background::get_type(),
475 [
476 'name' => 'background_overlay_hover',
477 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated > .elementor-background-overlay',
478 ]
479 );
480
481 $this->add_responsive_control(
482 'background_overlay_hover_opacity',
483 [
484 'label' => esc_html__( 'Opacity', 'elementor' ),
485 'type' => Controls_Manager::SLIDER,
486 'default' => [
487 'size' => .5,
488 ],
489 'range' => [
490 'px' => [
491 'max' => 1,
492 'step' => 0.01,
493 ],
494 ],
495 'selectors' => [
496 '{{WRAPPER}}:hover > .elementor-element-populated > .elementor-background-overlay' => 'opacity: {{SIZE}};',
497 ],
498 'condition' => [
499 'background_overlay_hover_background' => [ 'classic', 'gradient' ],
500 ],
501 ]
502 );
503
504 $this->add_group_control(
505 Group_Control_Css_Filter::get_type(),
506 [
507 'name' => 'css_filters_hover',
508 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated > .elementor-background-overlay',
509 ]
510 );
511
512 $this->add_control(
513 'background_overlay_hover_transition',
514 [
515 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
516 'type' => Controls_Manager::SLIDER,
517 'default' => [
518 'size' => 0.3,
519 ],
520 'range' => [
521 'px' => [
522 'min' => 0,
523 'max' => 3,
524 'step' => 0.1,
525 ],
526 ],
527 'render_type' => 'ui',
528 'separator' => 'before',
529 ]
530 );
531
532 $this->end_controls_tab();
533
534 $this->end_controls_tabs();
535
536 $this->end_controls_section();
537
538 $this->start_controls_section(
539 'section_border',
540 [
541 'label' => esc_html__( 'Border', 'elementor' ),
542 'tab' => Controls_Manager::TAB_STYLE,
543 ]
544 );
545
546 $this->start_controls_tabs( 'tabs_border' );
547
548 $this->start_controls_tab(
549 'tab_border_normal',
550 [
551 'label' => esc_html__( 'Normal', 'elementor' ),
552 ]
553 );
554
555 $this->add_group_control(
556 Group_Control_Border::get_type(),
557 [
558 'name' => 'border',
559 'selector' => '{{WRAPPER}} > .elementor-element-populated',
560 ]
561 );
562
563 $this->add_responsive_control(
564 'border_radius',
565 [
566 'label' => esc_html__( 'Border Radius', 'elementor' ),
567 'type' => Controls_Manager::DIMENSIONS,
568 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
569 'selectors' => [
570 '{{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}};',
571 ],
572 ]
573 );
574
575 $this->add_group_control(
576 Group_Control_Box_Shadow::get_type(),
577 [
578 'name' => 'box_shadow',
579 'selector' => '{{WRAPPER}} > .elementor-element-populated',
580 ]
581 );
582
583 $this->end_controls_tab();
584
585 $this->start_controls_tab(
586 'tab_border_hover',
587 [
588 'label' => esc_html__( 'Hover', 'elementor' ),
589 ]
590 );
591
592 $this->add_group_control(
593 Group_Control_Border::get_type(),
594 [
595 'name' => 'border_hover',
596 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated',
597 ]
598 );
599
600 $this->add_responsive_control(
601 'border_radius_hover',
602 [
603 'label' => esc_html__( 'Border Radius', 'elementor' ),
604 'type' => Controls_Manager::DIMENSIONS,
605 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
606 'selectors' => [
607 '{{WRAPPER}}:hover > .elementor-element-populated, {{WRAPPER}}:hover > .elementor-element-populated > .elementor-background-overlay' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
608 ],
609 ]
610 );
611
612 $this->add_group_control(
613 Group_Control_Box_Shadow::get_type(),
614 [
615 'name' => 'box_shadow_hover',
616 'selector' => '{{WRAPPER}}:hover > .elementor-element-populated',
617 ]
618 );
619
620 $this->add_control(
621 'border_hover_transition',
622 [
623 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
624 'type' => Controls_Manager::SLIDER,
625 'separator' => 'before',
626 'default' => [
627 'size' => 0.3,
628 ],
629 'range' => [
630 'px' => [
631 'min' => 0,
632 'max' => 3,
633 'step' => 0.1,
634 ],
635 ],
636 'conditions' => [
637 'relation' => 'or',
638 'terms' => [
639 [
640 'name' => 'background_background',
641 'operator' => '!==',
642 'value' => '',
643 ],
644 [
645 'name' => 'border_hover_border',
646 'operator' => '!==',
647 'value' => '',
648 ],
649 ],
650 ],
651 'selectors' => [
652 '{{WRAPPER}} > .elementor-element-populated' => 'transition: background {{background_hover_transition.SIZE}}s, border {{SIZE}}s, border-radius {{SIZE}}s, box-shadow {{SIZE}}s',
653 '{{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',
654 ],
655 ]
656 );
657
658 $this->end_controls_tab();
659
660 $this->end_controls_tabs();
661
662 $this->end_controls_section();
663
664 // Section Typography.
665 $this->start_controls_section(
666 'section_typo',
667 [
668 'label' => esc_html__( 'Typography', 'elementor' ),
669 'type' => Controls_Manager::SECTION,
670 'tab' => Controls_Manager::TAB_STYLE,
671 ]
672 );
673
674 $this->add_control(
675 'heading_color',
676 [
677 'label' => esc_html__( 'Heading Color', 'elementor' ),
678 'type' => Controls_Manager::COLOR,
679 'default' => '',
680 'selectors' => [
681 '{{WRAPPER}} .elementor-element-populated .elementor-heading-title' => 'color: {{VALUE}};',
682 ],
683 ]
684 );
685
686 $this->add_control(
687 'color_text',
688 [
689 'label' => esc_html__( 'Text Color', 'elementor' ),
690 'type' => Controls_Manager::COLOR,
691 'default' => '',
692 'selectors' => [
693 '{{WRAPPER}} > .elementor-element-populated' => 'color: {{VALUE}};',
694 ],
695 ]
696 );
697
698 $this->add_control(
699 'color_link',
700 [
701 'label' => esc_html__( 'Link Color', 'elementor' ),
702 'type' => Controls_Manager::COLOR,
703 'default' => '',
704 'selectors' => [
705 '{{WRAPPER}} .elementor-element-populated a' => 'color: {{VALUE}};',
706 ],
707 ]
708 );
709
710 $this->add_control(
711 'color_link_hover',
712 [
713 'label' => esc_html__( 'Link Hover Color', 'elementor' ),
714 'type' => Controls_Manager::COLOR,
715 'default' => '',
716 'selectors' => [
717 '{{WRAPPER}} .elementor-element-populated a:hover' => 'color: {{VALUE}};',
718 ],
719 ]
720 );
721
722 $this->add_responsive_control(
723 'text_align',
724 [
725 'label' => esc_html__( 'Text Align', 'elementor' ),
726 'type' => Controls_Manager::CHOOSE,
727 'options' => [
728 'left' => [
729 'title' => esc_html__( 'Left', 'elementor' ),
730 'icon' => 'eicon-text-align-left',
731 ],
732 'center' => [
733 'title' => esc_html__( 'Center', 'elementor' ),
734 'icon' => 'eicon-text-align-center',
735 ],
736 'right' => [
737 'title' => esc_html__( 'Right', 'elementor' ),
738 'icon' => 'eicon-text-align-right',
739 ],
740 'justify' => [
741 'title' => esc_html__( 'Justified', 'elementor' ),
742 'icon' => 'eicon-text-align-justify',
743 ],
744 ],
745 'selectors' => [
746 '{{WRAPPER}} > .elementor-element-populated' => 'text-align: {{VALUE}};',
747 ],
748 ]
749 );
750
751 $this->end_controls_section();
752
753 // Section Advanced.
754 $this->start_controls_section(
755 'section_advanced',
756 [
757 'label' => esc_html__( 'Advanced', 'elementor' ),
758 'type' => Controls_Manager::SECTION,
759 'tab' => Controls_Manager::TAB_ADVANCED,
760 ]
761 );
762
763 $this->add_responsive_control(
764 'margin',
765 [
766 'label' => esc_html__( 'Margin', 'elementor' ),
767 'type' => Controls_Manager::DIMENSIONS,
768 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
769 'selectors' => [
770 '{{WRAPPER}} > .elementor-element-populated' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};
771 --e-column-margin-right: {{RIGHT}}{{UNIT}}; --e-column-margin-left: {{LEFT}}{{UNIT}};',
772 ],
773 ]
774 );
775
776 $this->add_responsive_control(
777 'padding',
778 [
779 'label' => esc_html__( 'Padding', 'elementor' ),
780 'type' => Controls_Manager::DIMENSIONS,
781 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
782 'selectors' => [
783 '{{WRAPPER}} > .elementor-element-populated' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
784 ],
785 ]
786 );
787
788 $this->add_responsive_control(
789 'z_index',
790 [
791 'label' => esc_html__( 'Z-Index', 'elementor' ),
792 'type' => Controls_Manager::NUMBER,
793 'min' => 0,
794 'selectors' => [
795 '{{WRAPPER}}' => 'z-index: {{VALUE}};',
796 ],
797 ]
798 );
799
800 $this->add_control(
801 '_element_id',
802 [
803 'label' => esc_html__( 'CSS ID', 'elementor' ),
804 'type' => Controls_Manager::TEXT,
805 'default' => '',
806 'ai' => [
807 'active' => false,
808 ],
809 'dynamic' => [
810 'active' => true,
811 ],
812 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
813 'style_transfer' => false,
814 'classes' => 'elementor-control-direction-ltr',
815 ]
816 );
817
818 $this->add_control(
819 'css_classes',
820 [
821 'label' => esc_html__( 'CSS Classes', 'elementor' ),
822 'type' => Controls_Manager::TEXT,
823 'default' => '',
824 'ai' => [
825 'active' => false,
826 ],
827 'dynamic' => [
828 'active' => true,
829 ],
830 'prefix_class' => '',
831 'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor' ),
832 'classes' => 'elementor-control-direction-ltr',
833 ]
834 );
835
836 Plugin::$instance->controls_manager->add_display_conditions_controls( $this );
837
838 // TODO: Backward comparability for deprecated controls.
839 $this->add_control(
840 'screen_sm',
841 [
842 'type' => Controls_Manager::HIDDEN,
843 ]
844 );
845
846 $this->add_control(
847 'screen_sm_width',
848 [
849 'type' => Controls_Manager::HIDDEN,
850 'condition' => [
851 'screen_sm' => [ 'custom' ],
852 ],
853 'prefix_class' => 'elementor-sm-',
854 ]
855 );
856 // END Backward comparability.
857
858 $this->end_controls_section();
859
860 $this->start_controls_section(
861 'section_effects',
862 [
863 'label' => esc_html__( 'Motion Effects', 'elementor' ),
864 'tab' => Controls_Manager::TAB_ADVANCED,
865 ]
866 );
867
868 Plugin::$instance->controls_manager->add_motion_effects_promotion_control( $this );
869
870 $this->add_responsive_control(
871 'animation',
872 [
873 'label' => esc_html__( 'Entrance Animation', 'elementor' ),
874 'type' => Controls_Manager::ANIMATION,
875 'frontend_available' => true,
876 ]
877 );
878
879 $this->add_control(
880 'animation_duration',
881 [
882 'label' => esc_html__( 'Animation Duration', 'elementor' ),
883 'type' => Controls_Manager::SELECT,
884 'default' => '',
885 'options' => [
886 'slow' => esc_html__( 'Slow', 'elementor' ),
887 '' => esc_html__( 'Normal', 'elementor' ),
888 'fast' => esc_html__( 'Fast', 'elementor' ),
889 ],
890 'prefix_class' => 'animated-',
891 'condition' => [
892 'animation!' => '',
893 ],
894 ]
895 );
896
897 $this->add_control(
898 'animation_delay',
899 [
900 'label' => esc_html__( 'Animation Delay', 'elementor' ) . ' (ms)',
901 'type' => Controls_Manager::NUMBER,
902 'default' => '',
903 'min' => 0,
904 'step' => 100,
905 'condition' => [
906 'animation!' => '',
907 ],
908 'render_type' => 'none',
909 'frontend_available' => true,
910 ]
911 );
912
913 $this->end_controls_section();
914
915 $this->start_controls_section(
916 '_section_responsive',
917 [
918 'label' => esc_html__( 'Responsive', 'elementor' ),
919 'tab' => Controls_Manager::TAB_ADVANCED,
920 ]
921 );
922
923 $this->add_control(
924 'responsive_description',
925 [
926 'raw' => sprintf(
927 /* translators: 1: Link open tag, 2: Link close tag. */
928 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' ),
929 '<a href="javascript: $e.run( \'panel/close\' )">',
930 '</a>'
931 ),
932 'type' => Controls_Manager::RAW_HTML,
933 'content_classes' => 'elementor-descriptor',
934 ]
935 );
936
937 $this->add_hidden_device_controls();
938
939 $this->end_controls_section();
940
941 Plugin::$instance->controls_manager->add_custom_attributes_controls( $this );
942
943 Plugin::$instance->controls_manager->add_custom_css_controls( $this );
944 }
945
946 /**
947 * Render column output in the editor.
948 *
949 * Used to generate the live preview, using a Backbone JavaScript template.
950 *
951 * @since 2.9.0
952 * @access protected
953 */
954 protected function content_template() {
955 ?>
956 <div class="elementor-widget-wrap">
957 <div class="elementor-background-overlay"></div>
958 </div>
959 <?php
960 }
961
962 /**
963 * Before column rendering.
964 *
965 * Used to add stuff before the column element.
966 *
967 * @since 1.0.0
968 * @access public
969 */
970 public function before_render() {
971 $settings = $this->get_settings_for_display();
972
973 $overlay_background = $settings['background_overlay_background'] ?? '';
974 $overlay_hover_background = $settings['background_overlay_hover_background'] ?? '';
975
976 $has_background_overlay = in_array( $overlay_background, [ 'classic', 'gradient' ], true ) ||
977 in_array( $overlay_hover_background, [ 'classic', 'gradient' ], true );
978
979 $column_wrap_classes = [ 'elementor-widget-wrap' ];
980
981 if ( $this->get_children() ) {
982 $column_wrap_classes[] = 'elementor-element-populated';
983 }
984
985 $this->add_render_attribute( [
986 '_widget_wrapper' => [
987 'class' => $column_wrap_classes,
988 ],
989 '_background_overlay' => [
990 'class' => [ 'elementor-background-overlay' ],
991 ],
992 ] );
993 ?>
994 <<?php
995 // PHPCS - the method get_html_tag is safe.
996 echo $this->get_html_tag(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
997 ?> <?php $this->print_render_attribute_string( '_wrapper' ); ?>>
998 <div <?php $this->print_render_attribute_string( '_widget_wrapper' ); ?>>
999 <?php if ( $has_background_overlay ) : ?>
1000 <div <?php $this->print_render_attribute_string( '_background_overlay' ); ?>></div>
1001 <?php endif; ?>
1002 <?php
1003 }
1004
1005 /**
1006 * After column rendering.
1007 *
1008 * Used to add stuff after the column element.
1009 *
1010 * @since 1.0.0
1011 * @access public
1012 */
1013 public function after_render() {
1014 ?>
1015 </div>
1016 </<?php
1017 // PHPCS - the method get_html_tag is safe.
1018 echo $this->get_html_tag(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1019 <?php
1020 }
1021
1022 /**
1023 * Add column render attributes.
1024 *
1025 * Used to add attributes to the current column wrapper HTML tag.
1026 *
1027 * @since 1.3.0
1028 * @access protected
1029 */
1030 protected function add_render_attributes() {
1031
1032 $is_inner = $this->get_data( 'isInner' );
1033
1034 $column_type = ! empty( $is_inner ) ? 'inner' : 'top';
1035
1036 $settings = $this->get_settings();
1037
1038 $this->add_render_attribute(
1039 '_wrapper', 'class', [
1040 'elementor-column',
1041 'elementor-col-' . $settings['_column_size'],
1042 'elementor-' . $column_type . '-column',
1043 ]
1044 );
1045
1046 parent::add_render_attributes();
1047 }
1048
1049 /**
1050 * Get default child type.
1051 *
1052 * Retrieve the column child type based on element data.
1053 *
1054 * @since 1.0.0
1055 * @access protected
1056 *
1057 * @param array $element_data Element ID.
1058 *
1059 * @return Element_Base|false Column default child type.
1060 */
1061 protected function _get_default_child_type( array $element_data ) {
1062 if ( 'section' === $element_data['elType'] ) {
1063 return Plugin::$instance->elements_manager->get_element_types( 'section' );
1064 }
1065
1066 if ( 'container' === $element_data['elType'] ) {
1067 return Plugin::$instance->elements_manager->get_element_types( 'container' );
1068 }
1069
1070 // If the element doesn't exists (disabled element, experiment, etc.), return false to prevent errors.
1071 if ( empty( $element_data['widgetType'] ) ) {
1072 return false;
1073 }
1074
1075 return Plugin::$instance->widgets_manager->get_widget_types( $element_data['widgetType'] );
1076 }
1077
1078 /**
1079 * Get HTML tag.
1080 *
1081 * Retrieve the column element HTML tag.
1082 *
1083 * @since 1.5.3
1084 * @access private
1085 *
1086 * @return string Column HTML tag.
1087 */
1088 private function get_html_tag() {
1089 $html_tag = $this->get_settings( 'html_tag' );
1090
1091 if ( empty( $html_tag ) ) {
1092 $html_tag = 'div';
1093 }
1094
1095 return Utils::validate_html_tag( $html_tag );
1096 }
1097 }
1098