PluginProbe
Elementor Website Builder – more than just a page builder / 3.5.6
Elementor Website Builder – more than just a page builder v3.5.6
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 / widgets / common.php

common.php in Elementor Website Builder – more than just a page builder 3.5.6, at includes/widgets/common.php

1,587 lines 38.7 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 common widget.
12 *
13 * Elementor base widget that gives you all the advanced options of the basic
14 * widget.
15 *
16 * @since 1.0.0
17 */
18 class Widget_Common extends Widget_Base {
19
20 /**
21 * Get widget name.
22 *
23 * Retrieve common widget name.
24 *
25 * @since 1.0.0
26 * @access public
27 *
28 * @return string Widget name.
29 */
30 public function get_name() {
31 return 'common';
32 }
33
34 /**
35 * Show in panel.
36 *
37 * Whether to show the common widget in the panel or not.
38 *
39 * @since 1.0.0
40 * @access public
41 *
42 * @return bool Whether to show the widget in the panel.
43 */
44 public function show_in_panel() {
45 return false;
46 }
47
48 /**
49 * Get Responsive Device Args
50 *
51 * Receives an array of device args, and duplicates it for each active breakpoint.
52 * Returns an array of device args.
53 *
54 * @since 3.4.7
55 * @access protected
56 *
57 * @param array $args arguments to duplicate per breakpoint
58 * @param array $devices_to_exclude
59 *
60 * @return array responsive device args
61 */
62 protected function get_responsive_device_args( array $args, array $devices_to_exclude = [] ) {
63 $device_args = [];
64 $breakpoints = Breakpoints_Manager::get_default_config();
65
66 foreach ( $breakpoints as $breakpoint_key => $breakpoint ) {
67 // If the device is not excluded, add it to the device args array.
68 if ( ! in_array( $breakpoint_key, $devices_to_exclude, true ) ) {
69 $parsed_device_args = $this->parse_device_args_placeholders( $args, $breakpoint_key );
70
71 $device_args[ $breakpoint_key ] = $parsed_device_args;
72 }
73 }
74
75 return $device_args;
76 }
77
78 /**
79 * Parse Device Args Placeholders
80 *
81 * Receives an array of args. Iterates over the args, and replaces the {{DEVICE}} placeholder, if exists, with the
82 * passed breakpoint key.
83 *
84 * @since 3.4.7
85 * @access private
86 *
87 * @param array $args
88 * @param string $breakpoint_key
89 * @return array parsed device args
90 */
91 private function parse_device_args_placeholders( array $args, $breakpoint_key ) {
92 $parsed_args = [];
93
94 foreach ( $args as $arg_key => $arg_value ) {
95 $arg_key = str_replace( '{{DEVICE}}', $breakpoint_key, $arg_key );
96
97 if ( is_array( $arg_value ) ) {
98 $arg_value = $this->parse_device_args_placeholders( $arg_value, $breakpoint_key );
99 }
100
101 $parsed_args[ $arg_key ] = $arg_value;
102 }
103
104 return $parsed_args;
105 }
106
107 /**
108 * @param $shape String Shape name.
109 *
110 * @return string The shape path in the assets folder.
111 */
112 private function get_shape_url( $shape ) {
113 return ELEMENTOR_ASSETS_URL . 'mask-shapes/' . $shape . '.svg';
114 }
115
116 /**
117 * Return a translated user-friendly list of the available masking shapes.
118 *
119 * @param bool $add_custom Determine if the output should contain `Custom` options.
120 *
121 * @return array Array of shapes with their URL as key.
122 */
123 private function get_shapes( $add_custom = true ) {
124 $shapes = [
125 'circle' => esc_html__( 'Circle', 'elementor' ),
126 'flower' => esc_html__( 'Flower', 'elementor' ),
127 'sketch' => esc_html__( 'Sketch', 'elementor' ),
128 'triangle' => esc_html__( 'Triangle', 'elementor' ),
129 'blob' => esc_html__( 'Blob', 'elementor' ),
130 'hexagon' => esc_html__( 'Hexagon', 'elementor' ),
131 ];
132
133 if ( $add_custom ) {
134 $shapes['custom'] = esc_html__( 'Custom', 'elementor' );
135 }
136
137 return $shapes;
138 }
139
140 /**
141 * Gets a string of CSS rules to apply, and returns an array of selectors with those rules.
142 * This function has been created in order to deal with masking for image widget.
143 * For most of the widgets the mask is being applied to the wrapper itself, but in the case of an image widget,
144 * the `img` tag should be masked directly. So instead of writing a lot of selectors every time,
145 * this function builds both of those selectors easily.
146 *
147 * @param $rules string The CSS rules to apply.
148 *
149 * @return array Selectors with the rules applied.
150 */
151 private function get_mask_selectors( $rules ) {
152 $mask_selectors = [
153 'default' => '{{WRAPPER}}:not( .elementor-widget-image ) .elementor-widget-container',
154 'image' => '{{WRAPPER}}.elementor-widget-image .elementor-widget-container img',
155 ];
156
157 return [
158 $mask_selectors['default'] => $rules,
159 $mask_selectors['image'] => $rules,
160 ];
161 }
162
163 /**
164 * Register common widget controls.
165 *
166 * Adds different input fields to allow the user to change and customize the widget settings.
167 *
168 * @since 3.1.0
169 * @access protected
170 */
171 protected function register_controls() {
172 $this->start_controls_section(
173 '_section_style',
174 [
175 'label' => esc_html__( 'Advanced', 'elementor' ),
176 'tab' => Controls_Manager::TAB_ADVANCED,
177 ]
178 );
179
180 // Element Name for the Navigator
181 $this->add_control(
182 '_title',
183 [
184 'label' => esc_html__( 'Title', 'elementor' ),
185 'type' => Controls_Manager::HIDDEN,
186 'render_type' => 'none',
187 ]
188 );
189
190 $this->add_responsive_control(
191 '_margin',
192 [
193 'label' => esc_html__( 'Margin', 'elementor' ),
194 'type' => Controls_Manager::DIMENSIONS,
195 'size_units' => [ 'px', 'em', '%', 'rem' ],
196 'selectors' => [
197 '{{WRAPPER}} > .elementor-widget-container' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
198 ],
199 ]
200 );
201
202 $this->add_responsive_control(
203 '_padding',
204 [
205 'label' => esc_html__( 'Padding', 'elementor' ),
206 'type' => Controls_Manager::DIMENSIONS,
207 'size_units' => [ 'px', 'em', '%', 'rem' ],
208 'selectors' => [
209 '{{WRAPPER}} > .elementor-widget-container' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
210 ],
211 ]
212 );
213
214 $this->add_responsive_control(
215 '_z_index',
216 [
217 'label' => esc_html__( 'Z-Index', 'elementor' ),
218 'type' => Controls_Manager::NUMBER,
219 'selectors' => [
220 '{{WRAPPER}}' => 'z-index: {{VALUE}};',
221 ],
222 'separator' => 'before',
223 ]
224 );
225
226 $this->add_control(
227 '_element_id',
228 [
229 'label' => esc_html__( 'CSS ID', 'elementor' ),
230 'type' => Controls_Manager::TEXT,
231 'dynamic' => [
232 'active' => true,
233 ],
234 'default' => '',
235 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
236 'style_transfer' => false,
237 'classes' => 'elementor-control-direction-ltr',
238 ]
239 );
240
241 $this->add_control(
242 '_css_classes',
243 [
244 'label' => esc_html__( 'CSS Classes', 'elementor' ),
245 'type' => Controls_Manager::TEXT,
246 'dynamic' => [
247 'active' => true,
248 ],
249 'prefix_class' => '',
250 'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor' ),
251 'classes' => 'elementor-control-direction-ltr',
252 ]
253 );
254
255 $this->end_controls_section();
256
257 $this->start_controls_section(
258 'section_effects',
259 [
260 'label' => esc_html__( 'Motion Effects', 'elementor' ),
261 'tab' => Controls_Manager::TAB_ADVANCED,
262 ]
263 );
264
265 $this->add_responsive_control(
266 '_animation',
267 [
268 'label' => esc_html__( 'Entrance Animation', 'elementor' ),
269 'type' => Controls_Manager::ANIMATION,
270 'frontend_available' => true,
271 ]
272 );
273
274 $this->add_control(
275 'animation_duration',
276 [
277 'label' => esc_html__( 'Animation Duration', 'elementor' ),
278 'type' => Controls_Manager::SELECT,
279 'default' => '',
280 'options' => [
281 'slow' => esc_html__( 'Slow', 'elementor' ),
282 '' => esc_html__( 'Normal', 'elementor' ),
283 'fast' => esc_html__( 'Fast', 'elementor' ),
284 ],
285 'prefix_class' => 'animated-',
286 'condition' => [
287 '_animation!' => '',
288 ],
289 ]
290 );
291
292 $this->add_control(
293 '_animation_delay',
294 [
295 'label' => esc_html__( 'Animation Delay', 'elementor' ) . ' (ms)',
296 'type' => Controls_Manager::NUMBER,
297 'default' => '',
298 'min' => 0,
299 'step' => 100,
300 'condition' => [
301 '_animation!' => '',
302 ],
303 'render_type' => 'none',
304 'frontend_available' => true,
305 ]
306 );
307
308 $this->end_controls_section();
309
310 $this->start_controls_section(
311 '_section_transform',
312 [
313 'label' => esc_html__( 'Transform', 'elementor' ),
314 'tab' => Controls_Manager::TAB_ADVANCED,
315 ]
316 );
317
318 $this->start_controls_tabs( '_tabs_positioning' );
319
320 $transform_prefix_class = 'e-';
321 $transform_return_value = 'transform';
322
323 foreach ( [ '', '_hover' ] as $tab ) {
324 $state = '_hover' === $tab ? ':hover' : '';
325
326 $this->start_controls_tab(
327 "_tab_positioning{$tab}",
328 [
329 'label' => '' === $tab ? esc_html__( 'Normal', 'elementor' ) : esc_html__( 'Hover', 'elementor' ),
330 ]
331 );
332
333 $this->add_control(
334 "_transform_rotate_popover{$tab}",
335 [
336 'label' => esc_html__( 'Rotate', 'elementor' ),
337 'type' => Controls_Manager::POPOVER_TOGGLE,
338 'prefix_class' => $transform_prefix_class,
339 'return_value' => $transform_return_value,
340 ]
341 );
342
343 $this->start_popover();
344
345 $this->add_responsive_control(
346 "_transform_rotateZ_effect{$tab}",
347 [
348 'label' => esc_html__( 'Rotate', 'elementor' ),
349 'type' => Controls_Manager::SLIDER,
350 'range' => [
351 'px' => [
352 'min' => -360,
353 'max' => 360,
354 ],
355 ],
356 'selectors' => [
357 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-rotateZ: {{SIZE}}deg',
358 ],
359 'condition' => [
360 "_transform_rotate_popover{$tab}!" => '',
361 ],
362 'frontend_available' => true,
363 ]
364 );
365
366 $this->add_control(
367 "_transform_rotate_3d{$tab}",
368 [
369 'label' => esc_html__( '3D Rotate', 'elementor' ),
370 'type' => Controls_Manager::SWITCHER,
371 'label_on' => esc_html__( 'On', 'elementor' ),
372 'label_off' => esc_html__( 'Off', 'elementor' ),
373 'selectors' => [
374 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-rotateX: 1deg; --e-transform-perspective: 20px;',
375 ],
376 'condition' => [
377 "_transform_rotate_popover{$tab}!" => '',
378 ],
379 ]
380 );
381
382 $this->add_responsive_control(
383 "_transform_rotateX_effect{$tab}",
384 [
385 'label' => esc_html__( 'Rotate X', 'elementor' ),
386 'type' => Controls_Manager::SLIDER,
387 'range' => [
388 'px' => [
389 'min' => -360,
390 'max' => 360,
391 ],
392 ],
393 'condition' => [
394 "_transform_rotate_3d{$tab}!" => '',
395 "_transform_rotate_popover{$tab}!" => '',
396 ],
397 'selectors' => [
398 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-rotateX: {{SIZE}}deg;',
399 ],
400 'frontend_available' => true,
401 ]
402 );
403
404 $this->add_responsive_control(
405 "_transform_rotateY_effect{$tab}",
406 [
407 'label' => esc_html__( 'Rotate Y', 'elementor' ),
408 'type' => Controls_Manager::SLIDER,
409 'range' => [
410 'px' => [
411 'min' => -360,
412 'max' => 360,
413 ],
414 ],
415 'condition' => [
416 "_transform_rotate_3d{$tab}!" => '',
417 "_transform_rotate_popover{$tab}!" => '',
418 ],
419 'selectors' => [
420 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-rotateY: {{SIZE}}deg;',
421 ],
422 'frontend_available' => true,
423 ]
424 );
425
426 $this->add_responsive_control(
427 "_transform_perspective_effect{$tab}",
428 [
429 'label' => esc_html__( 'Perspective', 'elementor' ),
430 'type' => Controls_Manager::SLIDER,
431 'range' => [
432 'px' => [
433 'min' => 0,
434 'max' => 1000,
435 ],
436 ],
437 'condition' => [
438 "_transform_rotate_popover{$tab}!" => '',
439 "_transform_rotate_3d{$tab}!" => '',
440 ],
441 'selectors' => [
442 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-perspective: {{SIZE}}px',
443 ],
444 'frontend_available' => true,
445 ]
446 );
447
448 $this->end_popover();
449
450 $this->add_control(
451 "_transform_translate_popover{$tab}",
452 [
453 'label' => esc_html__( 'Offset', 'elementor' ),
454 'type' => Controls_Manager::POPOVER_TOGGLE,
455 'prefix_class' => $transform_prefix_class,
456 'return_value' => $transform_return_value,
457 ]
458 );
459
460 $this->start_popover();
461
462 $this->add_responsive_control(
463 "_transform_translateX_effect{$tab}",
464 [
465 'label' => esc_html__( 'Offset X', 'elementor' ),
466 'type' => Controls_Manager::SLIDER,
467 'size_units' => [ '%', 'px' ],
468 'range' => [
469 '%' => [
470 'min' => -100,
471 'max' => 100,
472 ],
473 'px' => [
474 'min' => -1000,
475 'max' => 1000,
476 ],
477 ],
478 'condition' => [
479 "_transform_translate_popover{$tab}!" => '',
480 ],
481 'selectors' => [
482 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-translateX: {{SIZE}}{{UNIT}};',
483 ],
484 'frontend_available' => true,
485 ]
486 );
487
488 $this->add_responsive_control(
489 "_transform_translateY_effect{$tab}",
490 [
491 'label' => esc_html__( 'Offset Y', 'elementor' ),
492 'type' => Controls_Manager::SLIDER,
493 'size_units' => [ '%', 'px' ],
494 'range' => [
495 '%' => [
496 'min' => -100,
497 'max' => 100,
498 ],
499 'px' => [
500 'min' => -1000,
501 'max' => 1000,
502 ],
503 ],
504 'condition' => [
505 "_transform_translate_popover{$tab}!" => '',
506 ],
507 'selectors' => [
508 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-translateY: {{SIZE}}{{UNIT}};',
509 ],
510 'frontend_available' => true,
511 ]
512 );
513
514 $this->end_popover();
515
516 $this->add_control(
517 "_transform_scale_popover{$tab}",
518 [
519 'label' => esc_html__( 'Scale', 'elementor' ),
520 'type' => Controls_Manager::POPOVER_TOGGLE,
521 'prefix_class' => $transform_prefix_class,
522 'return_value' => $transform_return_value,
523 ]
524 );
525
526 $this->start_popover();
527
528 $this->add_control(
529 "_transform_keep_proportions{$tab}",
530 [
531 'label' => esc_html__( 'Keep Proportions', 'elementor' ),
532 'type' => Controls_Manager::SWITCHER,
533 'label_on' => esc_html__( 'On', 'elementor' ),
534 'label_off' => esc_html__( 'Off', 'elementor' ),
535 'default' => 'yes',
536 ]
537 );
538
539 $this->add_responsive_control(
540 "_transform_scale_effect{$tab}",
541 [
542 'label' => esc_html__( 'Scale', 'elementor' ),
543 'type' => Controls_Manager::SLIDER,
544 'range' => [
545 'px' => [
546 'min' => 0,
547 'max' => 2,
548 'step' => 0.1,
549 ],
550 ],
551 'condition' => [
552 "_transform_scale_popover{$tab}!" => '',
553 "_transform_keep_proportions{$tab}!" => '',
554 ],
555 'selectors' => [
556 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-scale: {{SIZE}};',
557 ],
558 'frontend_available' => true,
559 ]
560 );
561
562 $this->add_responsive_control(
563 "_transform_scaleX_effect{$tab}",
564 [
565 'label' => esc_html__( 'Scale X', 'elementor' ),
566 'type' => Controls_Manager::SLIDER,
567 'range' => [
568 'px' => [
569 'min' => 0,
570 'max' => 2,
571 'step' => 0.1,
572 ],
573 ],
574 'condition' => [
575 "_transform_scale_popover{$tab}!" => '',
576 "_transform_keep_proportions{$tab}" => '',
577 ],
578 'selectors' => [
579 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-scaleX: {{SIZE}};',
580 ],
581 'frontend_available' => true,
582 ]
583 );
584
585 $this->add_responsive_control(
586 "_transform_scaleY_effect{$tab}",
587 [
588 'label' => esc_html__( 'Scale Y', 'elementor' ),
589 'type' => Controls_Manager::SLIDER,
590 'range' => [
591 'px' => [
592 'min' => 0,
593 'max' => 2,
594 'step' => 0.1,
595 ],
596 ],
597 'condition' => [
598 "_transform_scale_popover{$tab}!" => '',
599 "_transform_keep_proportions{$tab}" => '',
600 ],
601 'selectors' => [
602 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-scaleY: {{SIZE}};',
603 ],
604 'frontend_available' => true,
605 ]
606 );
607
608 $this->end_popover();
609
610 $this->add_control(
611 "_transform_skew_popover{$tab}",
612 [
613 'label' => esc_html__( 'Skew', 'elementor' ),
614 'type' => Controls_Manager::POPOVER_TOGGLE,
615 'prefix_class' => $transform_prefix_class,
616 'return_value' => $transform_return_value,
617 ]
618 );
619
620 $this->start_popover();
621
622 $this->add_responsive_control(
623 "_transform_skewX_effect{$tab}",
624 [
625 'label' => esc_html__( 'Skew X', 'elementor' ),
626 'type' => Controls_Manager::SLIDER,
627 'range' => [
628 'px' => [
629 'min' => -360,
630 'max' => 360,
631 ],
632 ],
633 'condition' => [
634 "_transform_skew_popover{$tab}!" => '',
635 ],
636 'selectors' => [
637 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-skewX: {{SIZE}}deg;',
638 ],
639 'frontend_available' => true,
640 ]
641 );
642
643 $this->add_responsive_control(
644 "_transform_skewY_effect{$tab}",
645 [
646 'label' => esc_html__( 'Skew Y', 'elementor' ),
647 'type' => Controls_Manager::SLIDER,
648 'range' => [
649 'px' => [
650 'min' => -360,
651 'max' => 360,
652 ],
653 ],
654 'condition' => [
655 "_transform_skew_popover{$tab}!" => '',
656 ],
657 'selectors' => [
658 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-skewY: {{SIZE}}deg;',
659 ],
660 'frontend_available' => true,
661 ]
662 );
663
664 $this->end_popover();
665
666 $this->add_control(
667 "_transform_flipX_effect{$tab}",
668 [
669 'label' => esc_html__( 'Flip Horizontal', 'elementor' ),
670 'type' => Controls_Manager::CHOOSE,
671 'options' => [
672 'transform' => [
673 'title' => esc_html__( 'Flip Horizontal', 'elementor' ),
674 'icon' => 'eicon-flip eicon-tilted',
675 ],
676 ],
677 'prefix_class' => $transform_prefix_class,
678 'selectors' => [
679 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-flipX: -1',
680 ],
681 'frontend_available' => true,
682 ]
683 );
684
685 $this->add_control(
686 "_transform_flipY_effect{$tab}",
687 [
688 'label' => esc_html__( 'Flip Vertical', 'elementor' ),
689 'type' => Controls_Manager::CHOOSE,
690 'options' => [
691 'transform' => [
692 'title' => esc_html__( 'Flip Vertical', 'elementor' ),
693 'icon' => 'eicon-flip',
694 ],
695 ],
696 'prefix_class' => $transform_prefix_class,
697 'selectors' => [
698 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-flipY: -1',
699 ],
700 'frontend_available' => true,
701 ]
702 );
703
704 if ( '_hover' === $tab ) {
705 $this->add_control(
706 '_transform_transition_hover',
707 [
708 'label' => esc_html__( 'Transition Duration (ms)', 'elementor' ),
709 'type' => Controls_Manager::SLIDER,
710 'range' => [
711 'px' => [
712 'min' => 100,
713 'max' => 10000,
714 ],
715 ],
716 'selectors' => [
717 '{{WRAPPER}} > .elementor-widget-container' => '--e-transform-transition-duration: {{SIZE}}ms',
718 ],
719 ]
720 );
721 }
722
723 ${"transform_origin_conditions{$tab}"} = [
724 [
725 'name' => "_transform_scale_popover{$tab}",
726 'operator' => '!=',
727 'value' => '',
728 ],
729 [
730 'name' => "_transform_rotate_popover{$tab}",
731 'operator' => '!=',
732 'value' => '',
733 ],
734 [
735 'name' => "_transform_flipX_effect{$tab}",
736 'operator' => '!=',
737 'value' => '',
738 ],
739 [
740 'name' => "_transform_flipY_effect{$tab}",
741 'operator' => '!=',
742 'value' => '',
743 ],
744 ];
745
746 $this->end_controls_tab();
747 }
748
749 $this->end_controls_tabs();
750
751 $transform_origin_conditions = [
752 'relation' => 'or',
753 'terms' => array_merge( $transform_origin_conditions, $transform_origin_conditions_hover ),
754 ];
755
756 // Will override motion effect transform-origin
757 $this->add_responsive_control(
758 'motion_fx_transform_x_anchor_point',
759 [
760 'label' => esc_html__( 'X Anchor Point', 'elementor' ),
761 'type' => Controls_Manager::CHOOSE,
762 'options' => [
763 'left' => [
764 'title' => esc_html__( 'Left', 'elementor' ),
765 'icon' => 'eicon-h-align-left',
766 ],
767 'center' => [
768 'title' => esc_html__( 'Center', 'elementor' ),
769 'icon' => 'eicon-h-align-center',
770 ],
771 'right' => [
772 'title' => esc_html__( 'Right', 'elementor' ),
773 'icon' => 'eicon-h-align-right',
774 ],
775 ],
776 'conditions' => $transform_origin_conditions,
777 'separator' => 'before',
778 'selectors' => [
779 '{{WRAPPER}}' => '--e-transform-origin-x: {{VALUE}}',
780 ],
781 ]
782 );
783
784 // Will override motion effect transform-origin
785 $this->add_responsive_control(
786 'motion_fx_transform_y_anchor_point',
787 [
788 'label' => esc_html__( 'Y Anchor Point', 'elementor' ),
789 'type' => Controls_Manager::CHOOSE,
790 'options' => [
791 'top' => [
792 'title' => esc_html__( 'Top', 'elementor' ),
793 'icon' => 'eicon-v-align-top',
794 ],
795 'center' => [
796 'title' => esc_html__( 'Center', 'elementor' ),
797 'icon' => 'eicon-v-align-middle',
798 ],
799 'bottom' => [
800 'title' => esc_html__( 'Bottom', 'elementor' ),
801 'icon' => 'eicon-v-align-bottom',
802 ],
803 ],
804 'conditions' => $transform_origin_conditions,
805 'selectors' => [
806 '{{WRAPPER}}' => '--e-transform-origin-y: {{VALUE}}',
807 ],
808 ]
809 );
810
811 $this->end_controls_section();
812
813 $this->start_controls_section(
814 '_section_background',
815 [
816 'label' => esc_html__( 'Background', 'elementor' ),
817 'tab' => Controls_Manager::TAB_ADVANCED,
818 ]
819 );
820
821 $this->start_controls_tabs( '_tabs_background' );
822
823 $this->start_controls_tab(
824 '_tab_background_normal',
825 [
826 'label' => esc_html__( 'Normal', 'elementor' ),
827 ]
828 );
829
830 $this->add_group_control(
831 Group_Control_Background::get_type(),
832 [
833 'name' => '_background',
834 'selector' => '{{WRAPPER}} > .elementor-widget-container',
835 ]
836 );
837
838 $this->end_controls_tab();
839
840 $this->start_controls_tab(
841 '_tab_background_hover',
842 [
843 'label' => esc_html__( 'Hover', 'elementor' ),
844 ]
845 );
846
847 $this->add_group_control(
848 Group_Control_Background::get_type(),
849 [
850 'name' => '_background_hover',
851 'selector' => '{{WRAPPER}}:hover .elementor-widget-container',
852 ]
853 );
854
855 $this->add_control(
856 '_background_hover_transition',
857 [
858 'label' => esc_html__( 'Transition Duration', 'elementor' ),
859 'type' => Controls_Manager::SLIDER,
860 'range' => [
861 'px' => [
862 'max' => 3,
863 'step' => 0.1,
864 ],
865 ],
866 'render_type' => 'ui',
867 'separator' => 'before',
868 'selectors' => [
869 '{{WRAPPER}} > .elementor-widget-container' => 'transition: background {{SIZE}}s',
870 ],
871 ]
872 );
873
874 $this->end_controls_tab();
875
876 $this->end_controls_tabs();
877
878 $this->end_controls_section();
879
880 $this->start_controls_section(
881 '_section_border',
882 [
883 'label' => esc_html__( 'Border', 'elementor' ),
884 'tab' => Controls_Manager::TAB_ADVANCED,
885 ]
886 );
887
888 $this->start_controls_tabs( '_tabs_border' );
889
890 $this->start_controls_tab(
891 '_tab_border_normal',
892 [
893 'label' => esc_html__( 'Normal', 'elementor' ),
894 ]
895 );
896
897 $this->add_group_control(
898 Group_Control_Border::get_type(),
899 [
900 'name' => '_border',
901 'selector' => '{{WRAPPER}} > .elementor-widget-container',
902 ]
903 );
904
905 $this->add_responsive_control(
906 '_border_radius',
907 [
908 'label' => esc_html__( 'Border Radius', 'elementor' ),
909 'type' => Controls_Manager::DIMENSIONS,
910 'size_units' => [ 'px', '%' ],
911 'selectors' => [
912 '{{WRAPPER}} > .elementor-widget-container' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
913 ],
914 ]
915 );
916
917 $this->add_group_control(
918 Group_Control_Box_Shadow::get_type(),
919 [
920 'name' => '_box_shadow',
921 'selector' => '{{WRAPPER}} > .elementor-widget-container',
922 ]
923 );
924
925 $this->end_controls_tab();
926
927 $this->start_controls_tab(
928 '_tab_border_hover',
929 [
930 'label' => esc_html__( 'Hover', 'elementor' ),
931 ]
932 );
933
934 $this->add_group_control(
935 Group_Control_Border::get_type(),
936 [
937 'name' => '_border_hover',
938 'selector' => '{{WRAPPER}}:hover .elementor-widget-container',
939 ]
940 );
941
942 $this->add_responsive_control(
943 '_border_radius_hover',
944 [
945 'label' => esc_html__( 'Border Radius', 'elementor' ),
946 'type' => Controls_Manager::DIMENSIONS,
947 'size_units' => [ 'px', '%' ],
948 'selectors' => [
949 '{{WRAPPER}}:hover > .elementor-widget-container' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
950 ],
951 ]
952 );
953
954 $this->add_group_control(
955 Group_Control_Box_Shadow::get_type(),
956 [
957 'name' => '_box_shadow_hover',
958 'selector' => '{{WRAPPER}}:hover .elementor-widget-container',
959 ]
960 );
961
962 $this->add_control(
963 '_border_hover_transition',
964 [
965 'label' => esc_html__( 'Transition Duration', 'elementor' ),
966 'type' => Controls_Manager::SLIDER,
967 'separator' => 'before',
968 'range' => [
969 'px' => [
970 'max' => 3,
971 'step' => 0.1,
972 ],
973 ],
974 'selectors' => [
975 '{{WRAPPER}} .elementor-widget-container' => 'transition: background {{_background_hover_transition.SIZE}}s, border {{SIZE}}s, border-radius {{SIZE}}s, box-shadow {{SIZE}}s',
976 ],
977 ]
978 );
979
980 $this->end_controls_tab();
981
982 $this->end_controls_tabs();
983
984 $this->end_controls_section();
985
986 $this->start_controls_section(
987 '_section_masking',
988 [
989 'label' => esc_html__( 'Mask', 'elementor' ),
990 'tab' => Controls_Manager::TAB_ADVANCED,
991 ]
992 );
993
994 $this->add_control(
995 '_mask_switch',
996 [
997 'label' => esc_html__( 'Mask', 'elementor' ),
998 'type' => Controls_Manager::SWITCHER,
999 'label_on' => esc_html__( 'On', 'elementor' ),
1000 'label_off' => esc_html__( 'Off', 'elementor' ),
1001 'default' => '',
1002 ]
1003 );
1004
1005 $this->add_control( '_mask_shape', [
1006 'label' => esc_html__( 'Shape', 'elementor' ),
1007 'type' => Controls_Manager::SELECT,
1008 'options' => $this->get_shapes(),
1009 'default' => 'circle',
1010 'selectors' => $this->get_mask_selectors( '-webkit-mask-image: url( ' . ELEMENTOR_ASSETS_URL . '/mask-shapes/{{VALUE}}.svg );' ),
1011 'condition' => [
1012 '_mask_switch!' => '',
1013 ],
1014 ] );
1015
1016 $this->add_control(
1017 '_mask_image',
1018 [
1019 'label' => esc_html__( 'Image', 'elementor' ),
1020 'type' => Controls_Manager::MEDIA,
1021 'media_type' => 'image',
1022 'should_include_svg_inline_option' => true,
1023 'library_type' => 'image/svg+xml',
1024 'dynamic' => [
1025 'active' => true,
1026 ],
1027 'selectors' => $this->get_mask_selectors( '-webkit-mask-image: url( {{URL}} );' ),
1028 'condition' => [
1029 '_mask_switch!' => '',
1030 '_mask_shape' => 'custom',
1031 ],
1032 ]
1033 );
1034
1035 $this->add_control(
1036 '_mask_notice',
1037 [
1038 'type' => Controls_Manager::HIDDEN,
1039 'raw' => esc_html__( 'Need More Shapes?', 'elementor' ) .
1040 '<br>' .
1041 sprintf(
1042 /* translators: 1: Link open tag, 2: Link close tag. */
1043 esc_html__( 'Explore additional Premium Shape packs and use them in your site. %1$sLearn More%2$s', 'elementor' ),
1044 '<a target="_blank" href="https://go.elementor.com/mask-control">',
1045 '</a>'
1046 ),
1047 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
1048 'condition' => [
1049 '_mask_switch!' => '',
1050 ],
1051 ]
1052 );
1053
1054 $this->add_responsive_control(
1055 '_mask_size',
1056 [
1057 'label' => esc_html__( 'Size', 'elementor' ),
1058 'type' => Controls_Manager::SELECT,
1059 'options' => [
1060 'contain' => esc_html__( 'Fit', 'elementor' ),
1061 'cover' => esc_html__( 'Fill', 'elementor' ),
1062 'custom' => esc_html__( 'Custom', 'elementor' ),
1063 ],
1064 'default' => 'contain',
1065 'selectors' => $this->get_mask_selectors( '-webkit-mask-size: {{VALUE}};' ),
1066 'condition' => [
1067 '_mask_switch!' => '',
1068 ],
1069 ]
1070 );
1071
1072 $this->add_responsive_control(
1073 '_mask_size_scale',
1074 [
1075 'label' => esc_html__( 'Scale', 'elementor' ),
1076 'type' => Controls_Manager::SLIDER,
1077 'size_units' => [ 'px', 'em', '%', 'vw' ],
1078 'range' => [
1079 'px' => [
1080 'min' => 0,
1081 'max' => 500,
1082 ],
1083 'em' => [
1084 'min' => 0,
1085 'max' => 100,
1086 ],
1087 '%' => [
1088 'min' => 0,
1089 'max' => 200,
1090 ],
1091 'vw' => [
1092 'min' => 0,
1093 'max' => 100,
1094 ],
1095 ],
1096 'default' => [
1097 'unit' => '%',
1098 'size' => 100,
1099 ],
1100 'selectors' => $this->get_mask_selectors( '-webkit-mask-size: {{SIZE}}{{UNIT}};' ),
1101 'condition' => [
1102 '_mask_switch!' => '',
1103 '_mask_size' => 'custom',
1104 ],
1105 ]
1106 );
1107
1108 $this->add_responsive_control(
1109 '_mask_position',
1110 [
1111 'label' => esc_html__( 'Position', 'elementor' ),
1112 'type' => Controls_Manager::SELECT,
1113 'options' => [
1114 'center center' => esc_html__( 'Center Center', 'elementor' ),
1115 'center left' => esc_html__( 'Center Left', 'elementor' ),
1116 'center right' => esc_html__( 'Center Right', 'elementor' ),
1117 'top center' => esc_html__( 'Top Center', 'elementor' ),
1118 'top left' => esc_html__( 'Top Left', 'elementor' ),
1119 'top right' => esc_html__( 'Top Right', 'elementor' ),
1120 'bottom center' => esc_html__( 'Bottom Center', 'elementor' ),
1121 'bottom left' => esc_html__( 'Bottom Left', 'elementor' ),
1122 'bottom right' => esc_html__( 'Bottom Right', 'elementor' ),
1123 'custom' => esc_html__( 'Custom', 'elementor' ),
1124 ],
1125 'default' => 'center center',
1126 'selectors' => $this->get_mask_selectors( '-webkit-mask-position: {{VALUE}};' ),
1127 'condition' => [
1128 '_mask_switch!' => '',
1129 ],
1130 ]
1131 );
1132
1133 $this->add_responsive_control(
1134 '_mask_position_x',
1135 [
1136 'label' => esc_html__( 'X Position', 'elementor' ),
1137 'type' => Controls_Manager::SLIDER,
1138 'size_units' => [ 'px', 'em', '%', 'vw' ],
1139 'range' => [
1140 'px' => [
1141 'min' => -500,
1142 'max' => 500,
1143 ],
1144 'em' => [
1145 'min' => -100,
1146 'max' => 100,
1147 ],
1148 '%' => [
1149 'min' => -100,
1150 'max' => 100,
1151 ],
1152 'vw' => [
1153 'min' => -100,
1154 'max' => 100,
1155 ],
1156 ],
1157 'default' => [
1158 'unit' => '%',
1159 'size' => 0,
1160 ],
1161 'selectors' => $this->get_mask_selectors( '-webkit-mask-position-x: {{SIZE}}{{UNIT}};' ),
1162 'condition' => [
1163 '_mask_switch!' => '',
1164 '_mask_position' => 'custom',
1165 ],
1166 ]
1167 );
1168
1169 $this->add_responsive_control(
1170 '_mask_position_y',
1171 [
1172 'label' => esc_html__( 'Y Position', 'elementor' ),
1173 'type' => Controls_Manager::SLIDER,
1174 'size_units' => [ 'px', 'em', '%', 'vw' ],
1175 'range' => [
1176 'px' => [
1177 'min' => -500,
1178 'max' => 500,
1179 ],
1180 'em' => [
1181 'min' => -100,
1182 'max' => 100,
1183 ],
1184 '%' => [
1185 'min' => -100,
1186 'max' => 100,
1187 ],
1188 'vw' => [
1189 'min' => -100,
1190 'max' => 100,
1191 ],
1192 ],
1193 'default' => [
1194 'unit' => '%',
1195 'size' => 0,
1196 ],
1197 'selectors' => $this->get_mask_selectors( '-webkit-mask-position-y: {{SIZE}}{{UNIT}};' ),
1198 'condition' => [
1199 '_mask_switch!' => '',
1200 '_mask_position' => 'custom',
1201 ],
1202 ]
1203 );
1204
1205 $this->add_responsive_control(
1206 '_mask_repeat',
1207 [
1208 'label' => esc_html__( 'Repeat', 'elementor' ),
1209 'type' => Controls_Manager::SELECT,
1210 'options' => [
1211 'no-repeat' => esc_html__( 'No-Repeat', 'elementor' ),
1212 'repeat' => esc_html__( 'Repeat', 'elementor' ),
1213 'repeat-x' => esc_html__( 'Repeat-X', 'elementor' ),
1214 'repeat-Y' => esc_html__( 'Repeat-Y', 'elementor' ),
1215 'round' => esc_html__( 'Round', 'elementor' ),
1216 'space' => esc_html__( 'Space', 'elementor' ),
1217 ],
1218 'default' => 'no-repeat',
1219 'selectors' => $this->get_mask_selectors( '-webkit-mask-repeat: {{VALUE}};' ),
1220 'condition' => [
1221 '_mask_switch!' => '',
1222 '_mask_size!' => 'cover',
1223 ],
1224 ]
1225 );
1226
1227 $this->end_controls_section();
1228
1229 $this->start_controls_section(
1230 '_section_position',
1231 [
1232 'label' => esc_html__( 'Positioning', 'elementor' ),
1233 'tab' => Controls_Manager::TAB_ADVANCED,
1234 ]
1235 );
1236
1237 $this->add_responsive_control(
1238 '_element_width',
1239 [
1240 'label' => esc_html__( 'Width', 'elementor' ),
1241 'type' => Controls_Manager::SELECT,
1242 'default' => '',
1243 'options' => [
1244 '' => esc_html__( 'Default', 'elementor' ),
1245 'inherit' => esc_html__( 'Full Width', 'elementor' ) . ' (100%)',
1246 'auto' => esc_html__( 'Inline', 'elementor' ) . ' (auto)',
1247 'initial' => esc_html__( 'Custom', 'elementor' ),
1248 ],
1249 'selectors_dictionary' => [
1250 'inherit' => '100%',
1251 ],
1252 'prefix_class' => 'elementor-widget%s__width-',
1253 'selectors' => [
1254 '{{WRAPPER}}' => 'width: {{VALUE}}; max-width: {{VALUE}}',
1255 ],
1256 ]
1257 );
1258
1259 $this->add_responsive_control(
1260 '_element_custom_width',
1261 [
1262 'label' => esc_html__( 'Custom Width', 'elementor' ),
1263 'type' => Controls_Manager::SLIDER,
1264 'range' => [
1265 'px' => [
1266 'max' => 1000,
1267 'step' => 1,
1268 ],
1269 '%' => [
1270 'max' => 100,
1271 'step' => 1,
1272 ],
1273 ],
1274 'condition' => [
1275 '_element_width' => 'initial',
1276 ],
1277 'device_args' => $this->get_responsive_device_args( [
1278 'condition' => [
1279 '_element_width_{{DEVICE}}' => [ 'initial' ],
1280 ],
1281 ] ),
1282 'size_units' => [ 'px', '%', 'vw' ],
1283 'selectors' => [
1284 '{{WRAPPER}}' => 'width: {{SIZE}}{{UNIT}}; max-width: {{SIZE}}{{UNIT}}',
1285 ],
1286 ]
1287 );
1288
1289 $this->add_responsive_control(
1290 '_element_vertical_align',
1291 [
1292 'label' => esc_html__( 'Vertical Align', 'elementor' ),
1293 'type' => Controls_Manager::CHOOSE,
1294 'options' => [
1295 'flex-start' => [
1296 'title' => esc_html__( 'Start', 'elementor' ),
1297 'icon' => 'eicon-v-align-top',
1298 ],
1299 'center' => [
1300 'title' => esc_html__( 'Center', 'elementor' ),
1301 'icon' => 'eicon-v-align-middle',
1302 ],
1303 'flex-end' => [
1304 'title' => esc_html__( 'End', 'elementor' ),
1305 'icon' => 'eicon-v-align-bottom',
1306 ],
1307 ],
1308 'condition' => [
1309 '_element_width!' => '',
1310 '_position' => '',
1311 ],
1312 'device_args' => $this->get_responsive_device_args( [
1313 'condition' => [
1314 '_element_width_{{DEVICE}}!' => '',
1315 '_position' => '',
1316 ],
1317 ] ),
1318 'selectors' => [
1319 '{{WRAPPER}}' => 'align-self: {{VALUE}}',
1320 ],
1321 ]
1322 );
1323
1324 $this->add_control(
1325 '_position_description',
1326 [
1327 'raw' => '<strong>' . esc_html__( 'Please note!', 'elementor' ) . '</strong> ' . esc_html__( 'Custom positioning is not considered best practice for responsive web design and should not be used too frequently.', 'elementor' ),
1328 'type' => Controls_Manager::RAW_HTML,
1329 'content_classes' => 'elementor-panel-alert elementor-panel-alert-warning',
1330 'render_type' => 'ui',
1331 'condition' => [
1332 '_position!' => '',
1333 ],
1334 ]
1335 );
1336
1337 $this->add_control(
1338 '_position',
1339 [
1340 'label' => esc_html__( 'Position', 'elementor' ),
1341 'type' => Controls_Manager::SELECT,
1342 'default' => '',
1343 'options' => [
1344 '' => esc_html__( 'Default', 'elementor' ),
1345 'absolute' => esc_html__( 'Absolute', 'elementor' ),
1346 'fixed' => esc_html__( 'Fixed', 'elementor' ),
1347 ],
1348 'prefix_class' => 'elementor-',
1349 'frontend_available' => true,
1350 ]
1351 );
1352
1353 $start = is_rtl() ? esc_html__( 'Right', 'elementor' ) : esc_html__( 'Left', 'elementor' );
1354 $end = ! is_rtl() ? esc_html__( 'Right', 'elementor' ) : esc_html__( 'Left', 'elementor' );
1355
1356 $this->add_control(
1357 '_offset_orientation_h',
1358 [
1359 'label' => esc_html__( 'Horizontal Orientation', 'elementor' ),
1360 'type' => Controls_Manager::CHOOSE,
1361 'toggle' => false,
1362 'default' => 'start',
1363 'options' => [
1364 'start' => [
1365 'title' => $start,
1366 'icon' => 'eicon-h-align-left',
1367 ],
1368 'end' => [
1369 'title' => $end,
1370 'icon' => 'eicon-h-align-right',
1371 ],
1372 ],
1373 'classes' => 'elementor-control-start-end',
1374 'render_type' => 'ui',
1375 'condition' => [
1376 '_position!' => '',
1377 ],
1378 ]
1379 );
1380
1381 $this->add_responsive_control(
1382 '_offset_x',
1383 [
1384 'label' => esc_html__( 'Offset', 'elementor' ),
1385 'type' => Controls_Manager::SLIDER,
1386 'range' => [
1387 'px' => [
1388 'min' => -1000,
1389 'max' => 1000,
1390 'step' => 1,
1391 ],
1392 '%' => [
1393 'min' => -200,
1394 'max' => 200,
1395 ],
1396 'vw' => [
1397 'min' => -200,
1398 'max' => 200,
1399 ],
1400 'vh' => [
1401 'min' => -200,
1402 'max' => 200,
1403 ],
1404 ],
1405 'default' => [
1406 'size' => '0',
1407 ],
1408 'size_units' => [ 'px', '%', 'vw', 'vh' ],
1409 'selectors' => [
1410 'body:not(.rtl) {{WRAPPER}}' => 'left: {{SIZE}}{{UNIT}}',
1411 'body.rtl {{WRAPPER}}' => 'right: {{SIZE}}{{UNIT}}',
1412 ],
1413 'condition' => [
1414 '_offset_orientation_h!' => 'end',
1415 '_position!' => '',
1416 ],
1417 ]
1418 );
1419
1420 $this->add_responsive_control(
1421 '_offset_x_end',
1422 [
1423 'label' => esc_html__( 'Offset', 'elementor' ),
1424 'type' => Controls_Manager::SLIDER,
1425 'range' => [
1426 'px' => [
1427 'min' => -1000,
1428 'max' => 1000,
1429 'step' => 0.1,
1430 ],
1431 '%' => [
1432 'min' => -200,
1433 'max' => 200,
1434 ],
1435 'vw' => [
1436 'min' => -200,
1437 'max' => 200,
1438 ],
1439 'vh' => [
1440 'min' => -200,
1441 'max' => 200,
1442 ],
1443 ],
1444 'default' => [
1445 'size' => '0',
1446 ],
1447 'size_units' => [ 'px', '%', 'vw', 'vh' ],
1448 'selectors' => [
1449 'body:not(.rtl) {{WRAPPER}}' => 'right: {{SIZE}}{{UNIT}}',
1450 'body.rtl {{WRAPPER}}' => 'left: {{SIZE}}{{UNIT}}',
1451 ],
1452 'condition' => [
1453 '_offset_orientation_h' => 'end',
1454 '_position!' => '',
1455 ],
1456 ]
1457 );
1458
1459 $this->add_control(
1460 '_offset_orientation_v',
1461 [
1462 'label' => esc_html__( 'Vertical Orientation', 'elementor' ),
1463 'type' => Controls_Manager::CHOOSE,
1464 'toggle' => false,
1465 'default' => 'start',
1466 'options' => [
1467 'start' => [
1468 'title' => esc_html__( 'Top', 'elementor' ),
1469 'icon' => 'eicon-v-align-top',
1470 ],
1471 'end' => [
1472 'title' => esc_html__( 'Bottom', 'elementor' ),
1473 'icon' => 'eicon-v-align-bottom',
1474 ],
1475 ],
1476 'render_type' => 'ui',
1477 'condition' => [
1478 '_position!' => '',
1479 ],
1480 ]
1481 );
1482
1483 $this->add_responsive_control(
1484 '_offset_y',
1485 [
1486 'label' => esc_html__( 'Offset', 'elementor' ),
1487 'type' => Controls_Manager::SLIDER,
1488 'range' => [
1489 'px' => [
1490 'min' => -1000,
1491 'max' => 1000,
1492 'step' => 1,
1493 ],
1494 '%' => [
1495 'min' => -200,
1496 'max' => 200,
1497 ],
1498 'vh' => [
1499 'min' => -200,
1500 'max' => 200,
1501 ],
1502 'vw' => [
1503 'min' => -200,
1504 'max' => 200,
1505 ],
1506 ],
1507 'size_units' => [ 'px', '%', 'vh', 'vw' ],
1508 'default' => [
1509 'size' => '0',
1510 ],
1511 'selectors' => [
1512 '{{WRAPPER}}' => 'top: {{SIZE}}{{UNIT}}',
1513 ],
1514 'condition' => [
1515 '_offset_orientation_v!' => 'end',
1516 '_position!' => '',
1517 ],
1518 ]
1519 );
1520
1521 $this->add_responsive_control(
1522 '_offset_y_end',
1523 [
1524 'label' => esc_html__( 'Offset', 'elementor' ),
1525 'type' => Controls_Manager::SLIDER,
1526 'range' => [
1527 'px' => [
1528 'min' => -1000,
1529 'max' => 1000,
1530 'step' => 1,
1531 ],
1532 '%' => [
1533 'min' => -200,
1534 'max' => 200,
1535 ],
1536 'vh' => [
1537 'min' => -200,
1538 'max' => 200,
1539 ],
1540 'vw' => [
1541 'min' => -200,
1542 'max' => 200,
1543 ],
1544 ],
1545 'size_units' => [ 'px', '%', 'vh', 'vw' ],
1546 'default' => [
1547 'size' => '0',
1548 ],
1549 'selectors' => [
1550 '{{WRAPPER}}' => 'bottom: {{SIZE}}{{UNIT}}',
1551 ],
1552 'condition' => [
1553 '_offset_orientation_v' => 'end',
1554 '_position!' => '',
1555 ],
1556 ]
1557 );
1558
1559 $this->end_controls_section();
1560
1561 $this->start_controls_section(
1562 '_section_responsive',
1563 [
1564 'label' => esc_html__( 'Responsive', 'elementor' ),
1565 'tab' => Controls_Manager::TAB_ADVANCED,
1566 ]
1567 );
1568
1569 $this->add_control(
1570 'responsive_description',
1571 [
1572 'raw' => esc_html__( 'Responsive visibility will take effect only on preview or live page, and not while editing in Elementor.', 'elementor' ),
1573 'type' => Controls_Manager::RAW_HTML,
1574 'content_classes' => 'elementor-descriptor',
1575 ]
1576 );
1577
1578 $this->add_hidden_device_controls();
1579
1580 $this->end_controls_section();
1581
1582 Plugin::$instance->controls_manager->add_custom_attributes_controls( $this );
1583
1584 Plugin::$instance->controls_manager->add_custom_css_controls( $this );
1585 }
1586 }
1587