PluginProbe
Elementor Website Builder – more than just a page builder / 3.4.8
Elementor Website Builder – more than just a page builder v3.4.8
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.4.8, at includes/widgets/common.php

1,082 lines 26.0 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 'min' => 0,
220 'selectors' => [
221 '{{WRAPPER}}' => 'z-index: {{VALUE}};',
222 ],
223 'separator' => 'before',
224 ]
225 );
226
227 $this->add_control(
228 '_element_id',
229 [
230 'label' => esc_html__( 'CSS ID', 'elementor' ),
231 'type' => Controls_Manager::TEXT,
232 'dynamic' => [
233 'active' => true,
234 ],
235 'default' => '',
236 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
237 'style_transfer' => false,
238 'classes' => 'elementor-control-direction-ltr',
239 ]
240 );
241
242 $this->add_control(
243 '_css_classes',
244 [
245 'label' => esc_html__( 'CSS Classes', 'elementor' ),
246 'type' => Controls_Manager::TEXT,
247 'dynamic' => [
248 'active' => true,
249 ],
250 'prefix_class' => '',
251 'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor' ),
252 'classes' => 'elementor-control-direction-ltr',
253 ]
254 );
255
256 $this->end_controls_section();
257
258 $this->start_controls_section(
259 'section_effects',
260 [
261 'label' => esc_html__( 'Motion Effects', 'elementor' ),
262 'tab' => Controls_Manager::TAB_ADVANCED,
263 ]
264 );
265
266 $this->add_responsive_control(
267 '_animation',
268 [
269 'label' => esc_html__( 'Entrance Animation', 'elementor' ),
270 'type' => Controls_Manager::ANIMATION,
271 'frontend_available' => true,
272 ]
273 );
274
275 $this->add_control(
276 'animation_duration',
277 [
278 'label' => esc_html__( 'Animation Duration', 'elementor' ),
279 'type' => Controls_Manager::SELECT,
280 'default' => '',
281 'options' => [
282 'slow' => esc_html__( 'Slow', 'elementor' ),
283 '' => esc_html__( 'Normal', 'elementor' ),
284 'fast' => esc_html__( 'Fast', 'elementor' ),
285 ],
286 'prefix_class' => 'animated-',
287 'condition' => [
288 '_animation!' => '',
289 ],
290 ]
291 );
292
293 $this->add_control(
294 '_animation_delay',
295 [
296 'label' => esc_html__( 'Animation Delay', 'elementor' ) . ' (ms)',
297 'type' => Controls_Manager::NUMBER,
298 'default' => '',
299 'min' => 0,
300 'step' => 100,
301 'condition' => [
302 '_animation!' => '',
303 ],
304 'render_type' => 'none',
305 'frontend_available' => true,
306 ]
307 );
308
309 $this->end_controls_section();
310
311 $this->start_controls_section(
312 '_section_background',
313 [
314 'label' => esc_html__( 'Background', 'elementor' ),
315 'tab' => Controls_Manager::TAB_ADVANCED,
316 ]
317 );
318
319 $this->start_controls_tabs( '_tabs_background' );
320
321 $this->start_controls_tab(
322 '_tab_background_normal',
323 [
324 'label' => esc_html__( 'Normal', 'elementor' ),
325 ]
326 );
327
328 $this->add_group_control(
329 Group_Control_Background::get_type(),
330 [
331 'name' => '_background',
332 'selector' => '{{WRAPPER}} > .elementor-widget-container',
333 ]
334 );
335
336 $this->end_controls_tab();
337
338 $this->start_controls_tab(
339 '_tab_background_hover',
340 [
341 'label' => esc_html__( 'Hover', 'elementor' ),
342 ]
343 );
344
345 $this->add_group_control(
346 Group_Control_Background::get_type(),
347 [
348 'name' => '_background_hover',
349 'selector' => '{{WRAPPER}}:hover .elementor-widget-container',
350 ]
351 );
352
353 $this->add_control(
354 '_background_hover_transition',
355 [
356 'label' => esc_html__( 'Transition Duration', 'elementor' ),
357 'type' => Controls_Manager::SLIDER,
358 'range' => [
359 'px' => [
360 'max' => 3,
361 'step' => 0.1,
362 ],
363 ],
364 'render_type' => 'ui',
365 'separator' => 'before',
366 'selectors' => [
367 '{{WRAPPER}} > .elementor-widget-container' => 'transition: background {{SIZE}}s',
368 ],
369 ]
370 );
371
372 $this->end_controls_tab();
373
374 $this->end_controls_tabs();
375
376 $this->end_controls_section();
377
378 $this->start_controls_section(
379 '_section_border',
380 [
381 'label' => esc_html__( 'Border', 'elementor' ),
382 'tab' => Controls_Manager::TAB_ADVANCED,
383 ]
384 );
385
386 $this->start_controls_tabs( '_tabs_border' );
387
388 $this->start_controls_tab(
389 '_tab_border_normal',
390 [
391 'label' => esc_html__( 'Normal', 'elementor' ),
392 ]
393 );
394
395 $this->add_group_control(
396 Group_Control_Border::get_type(),
397 [
398 'name' => '_border',
399 'selector' => '{{WRAPPER}} > .elementor-widget-container',
400 ]
401 );
402
403 $this->add_responsive_control(
404 '_border_radius',
405 [
406 'label' => esc_html__( 'Border Radius', 'elementor' ),
407 'type' => Controls_Manager::DIMENSIONS,
408 'size_units' => [ 'px', '%' ],
409 'selectors' => [
410 '{{WRAPPER}} > .elementor-widget-container' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
411 ],
412 ]
413 );
414
415 $this->add_group_control(
416 Group_Control_Box_Shadow::get_type(),
417 [
418 'name' => '_box_shadow',
419 'selector' => '{{WRAPPER}} > .elementor-widget-container',
420 ]
421 );
422
423 $this->end_controls_tab();
424
425 $this->start_controls_tab(
426 '_tab_border_hover',
427 [
428 'label' => esc_html__( 'Hover', 'elementor' ),
429 ]
430 );
431
432 $this->add_group_control(
433 Group_Control_Border::get_type(),
434 [
435 'name' => '_border_hover',
436 'selector' => '{{WRAPPER}}:hover .elementor-widget-container',
437 ]
438 );
439
440 $this->add_responsive_control(
441 '_border_radius_hover',
442 [
443 'label' => esc_html__( 'Border Radius', 'elementor' ),
444 'type' => Controls_Manager::DIMENSIONS,
445 'size_units' => [ 'px', '%' ],
446 'selectors' => [
447 '{{WRAPPER}}:hover > .elementor-widget-container' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
448 ],
449 ]
450 );
451
452 $this->add_group_control(
453 Group_Control_Box_Shadow::get_type(),
454 [
455 'name' => '_box_shadow_hover',
456 'selector' => '{{WRAPPER}}:hover .elementor-widget-container',
457 ]
458 );
459
460 $this->add_control(
461 '_border_hover_transition',
462 [
463 'label' => esc_html__( 'Transition Duration', 'elementor' ),
464 'type' => Controls_Manager::SLIDER,
465 'separator' => 'before',
466 'range' => [
467 'px' => [
468 'max' => 3,
469 'step' => 0.1,
470 ],
471 ],
472 'selectors' => [
473 '{{WRAPPER}} .elementor-widget-container' => 'transition: background {{_background_hover_transition.SIZE}}s, border {{SIZE}}s, border-radius {{SIZE}}s, box-shadow {{SIZE}}s',
474 ],
475 ]
476 );
477
478 $this->end_controls_tab();
479
480 $this->end_controls_tabs();
481
482 $this->end_controls_section();
483
484 $this->start_controls_section(
485 '_section_masking',
486 [
487 'label' => esc_html__( 'Mask', 'elementor' ),
488 'tab' => Controls_Manager::TAB_ADVANCED,
489 ]
490 );
491
492 $this->add_control(
493 '_mask_switch',
494 [
495 'label' => esc_html__( 'Mask', 'elementor' ),
496 'type' => Controls_Manager::SWITCHER,
497 'label_on' => esc_html__( 'On', 'elementor' ),
498 'label_off' => esc_html__( 'Off', 'elementor' ),
499 'default' => '',
500 ]
501 );
502
503 $this->add_control(
504 '_mask_shape',
505 [
506 'label' => esc_html__( 'Shape', 'elementor' ),
507 'type' => Controls_Manager::SELECT,
508 'options' => $this->get_shapes(),
509 'default' => 'circle',
510 'selectors' => $this->get_mask_selectors( '-webkit-mask-image: url( ' . ELEMENTOR_ASSETS_URL . '/mask-shapes/{{VALUE}}.svg );' ),
511 'condition' => [
512 '_mask_switch!' => '',
513 ],
514 ]
515 );
516
517 $this->add_control(
518 '_mask_image',
519 [
520 'label' => esc_html__( 'Image', 'elementor' ),
521 'type' => Controls_Manager::MEDIA,
522 'media_type' => 'image',
523 'should_include_svg_inline_option' => true,
524 'library_type' => 'image/svg+xml',
525 'dynamic' => [
526 'active' => true,
527 ],
528 'selectors' => $this->get_mask_selectors( '-webkit-mask-image: url( {{URL}} );' ),
529 'condition' => [
530 '_mask_switch!' => '',
531 '_mask_shape' => 'custom',
532 ],
533 ]
534 );
535
536 $this->add_control(
537 '_mask_notice',
538 [
539 'type' => Controls_Manager::HIDDEN,
540 'raw' => esc_html__( 'Need More Shapes?', 'elementor' ) .
541 '<br>' .
542 sprintf(
543 /* translators: 1: Link open tag, 2: Link close tag. */
544 esc_html__( 'Explore additional Premium Shape packs and use them in your site. %1$sLearn More%2$s', 'elementor' ),
545 '<a target="_blank" href="https://go.elementor.com/mask-control">',
546 '</a>'
547 ),
548 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
549 'condition' => [
550 '_mask_switch!' => '',
551 ],
552 ]
553 );
554
555 $this->add_responsive_control(
556 '_mask_size',
557 [
558 'label' => esc_html__( 'Size', 'elementor' ),
559 'type' => Controls_Manager::SELECT,
560 'options' => [
561 'contain' => esc_html__( 'Fit', 'elementor' ),
562 'cover' => esc_html__( 'Fill', 'elementor' ),
563 'custom' => esc_html__( 'Custom', 'elementor' ),
564 ],
565 'default' => 'contain',
566 'selectors' => $this->get_mask_selectors( '-webkit-mask-size: {{VALUE}};' ),
567 'condition' => [
568 '_mask_switch!' => '',
569 ],
570 ]
571 );
572
573 $this->add_responsive_control(
574 '_mask_size_scale',
575 [
576 'label' => esc_html__( 'Scale', 'elementor' ),
577 'type' => Controls_Manager::SLIDER,
578 'size_units' => [ 'px', 'em', '%', 'vw' ],
579 'range' => [
580 'px' => [
581 'min' => 0,
582 'max' => 500,
583 ],
584 'em' => [
585 'min' => 0,
586 'max' => 100,
587 ],
588 '%' => [
589 'min' => 0,
590 'max' => 200,
591 ],
592 'vw' => [
593 'min' => 0,
594 'max' => 100,
595 ],
596 ],
597 'default' => [
598 'unit' => '%',
599 'size' => 100,
600 ],
601 'selectors' => $this->get_mask_selectors( '-webkit-mask-size: {{SIZE}}{{UNIT}};' ),
602 'condition' => [
603 '_mask_switch!' => '',
604 '_mask_size' => 'custom',
605 ],
606 ]
607 );
608
609 $this->add_responsive_control(
610 '_mask_position',
611 [
612 'label' => esc_html__( 'Position', 'elementor' ),
613 'type' => Controls_Manager::SELECT,
614 'options' => [
615 'center center' => esc_html__( 'Center Center', 'elementor' ),
616 'center left' => esc_html__( 'Center Left', 'elementor' ),
617 'center right' => esc_html__( 'Center Right', 'elementor' ),
618 'top center' => esc_html__( 'Top Center', 'elementor' ),
619 'top left' => esc_html__( 'Top Left', 'elementor' ),
620 'top right' => esc_html__( 'Top Right', 'elementor' ),
621 'bottom center' => esc_html__( 'Bottom Center', 'elementor' ),
622 'bottom left' => esc_html__( 'Bottom Left', 'elementor' ),
623 'bottom right' => esc_html__( 'Bottom Right', 'elementor' ),
624 'custom' => esc_html__( 'Custom', 'elementor' ),
625 ],
626 'default' => 'center center',
627 'selectors' => $this->get_mask_selectors( '-webkit-mask-position: {{VALUE}};' ),
628 'condition' => [
629 '_mask_switch!' => '',
630 ],
631 ]
632 );
633
634 $this->add_responsive_control(
635 '_mask_position_x',
636 [
637 'label' => esc_html__( 'X Position', 'elementor' ),
638 'type' => Controls_Manager::SLIDER,
639 'size_units' => [ 'px', 'em', '%', 'vw' ],
640 'range' => [
641 'px' => [
642 'min' => -500,
643 'max' => 500,
644 ],
645 'em' => [
646 'min' => -100,
647 'max' => 100,
648 ],
649 '%' => [
650 'min' => -100,
651 'max' => 100,
652 ],
653 'vw' => [
654 'min' => -100,
655 'max' => 100,
656 ],
657 ],
658 'default' => [
659 'unit' => '%',
660 'size' => 0,
661 ],
662 'selectors' => $this->get_mask_selectors( '-webkit-mask-position-x: {{SIZE}}{{UNIT}};' ),
663 'condition' => [
664 '_mask_switch!' => '',
665 '_mask_position' => 'custom',
666 ],
667 ]
668 );
669
670 $this->add_responsive_control(
671 '_mask_position_y',
672 [
673 'label' => esc_html__( 'Y Position', 'elementor' ),
674 'type' => Controls_Manager::SLIDER,
675 'size_units' => [ 'px', 'em', '%', 'vw' ],
676 'range' => [
677 'px' => [
678 'min' => -500,
679 'max' => 500,
680 ],
681 'em' => [
682 'min' => -100,
683 'max' => 100,
684 ],
685 '%' => [
686 'min' => -100,
687 'max' => 100,
688 ],
689 'vw' => [
690 'min' => -100,
691 'max' => 100,
692 ],
693 ],
694 'default' => [
695 'unit' => '%',
696 'size' => 0,
697 ],
698 'selectors' => $this->get_mask_selectors( '-webkit-mask-position-y: {{SIZE}}{{UNIT}};' ),
699 'condition' => [
700 '_mask_switch!' => '',
701 '_mask_position' => 'custom',
702 ],
703 ]
704 );
705
706 $this->add_responsive_control(
707 '_mask_repeat',
708 [
709 'label' => esc_html__( 'Repeat', 'elementor' ),
710 'type' => Controls_Manager::SELECT,
711 'options' => [
712 'no-repeat' => esc_html__( 'No-Repeat', 'elementor' ),
713 'repeat' => esc_html__( 'Repeat', 'elementor' ),
714 'repeat-x' => esc_html__( 'Repeat-X', 'elementor' ),
715 'repeat-Y' => esc_html__( 'Repeat-Y', 'elementor' ),
716 'round' => esc_html__( 'Round', 'elementor' ),
717 'space' => esc_html__( 'Space', 'elementor' ),
718 ],
719 'default' => 'no-repeat',
720 'selectors' => $this->get_mask_selectors( '-webkit-mask-repeat: {{VALUE}};' ),
721 'condition' => [
722 '_mask_switch!' => '',
723 '_mask_size!' => 'cover',
724 ],
725 ]
726 );
727
728 $this->end_controls_section();
729
730 $this->start_controls_section(
731 '_section_position',
732 [
733 'label' => esc_html__( 'Positioning', 'elementor' ),
734 'tab' => Controls_Manager::TAB_ADVANCED,
735 ]
736 );
737
738 $this->add_responsive_control(
739 '_element_width',
740 [
741 'label' => esc_html__( 'Width', 'elementor' ),
742 'type' => Controls_Manager::SELECT,
743 'default' => '',
744 'options' => [
745 '' => esc_html__( 'Default', 'elementor' ),
746 'inherit' => esc_html__( 'Full Width', 'elementor' ) . ' (100%)',
747 'auto' => esc_html__( 'Inline', 'elementor' ) . ' (auto)',
748 'initial' => esc_html__( 'Custom', 'elementor' ),
749 ],
750 'selectors_dictionary' => [
751 'inherit' => '100%',
752 ],
753 'prefix_class' => 'elementor-widget%s__width-',
754 'selectors' => [
755 '{{WRAPPER}}' => 'width: {{VALUE}}; max-width: {{VALUE}}',
756 ],
757 ]
758 );
759
760 $this->add_responsive_control(
761 '_element_custom_width',
762 [
763 'label' => esc_html__( 'Custom Width', 'elementor' ),
764 'type' => Controls_Manager::SLIDER,
765 'range' => [
766 'px' => [
767 'max' => 1000,
768 'step' => 1,
769 ],
770 '%' => [
771 'max' => 100,
772 'step' => 1,
773 ],
774 ],
775 'condition' => [
776 '_element_width' => 'initial',
777 ],
778 'device_args' => $this->get_responsive_device_args( [
779 'condition' => [
780 '_element_width_{{DEVICE}}' => [ 'initial' ],
781 ],
782 ] ),
783 'size_units' => [ 'px', '%', 'vw' ],
784 'selectors' => [
785 '{{WRAPPER}}' => 'width: {{SIZE}}{{UNIT}}; max-width: {{SIZE}}{{UNIT}}',
786 ],
787 ]
788 );
789
790 $this->add_responsive_control(
791 '_element_vertical_align',
792 [
793 'label' => esc_html__( 'Vertical Align', 'elementor' ),
794 'type' => Controls_Manager::CHOOSE,
795 'options' => [
796 'flex-start' => [
797 'title' => esc_html__( 'Start', 'elementor' ),
798 'icon' => 'eicon-v-align-top',
799 ],
800 'center' => [
801 'title' => esc_html__( 'Center', 'elementor' ),
802 'icon' => 'eicon-v-align-middle',
803 ],
804 'flex-end' => [
805 'title' => esc_html__( 'End', 'elementor' ),
806 'icon' => 'eicon-v-align-bottom',
807 ],
808 ],
809 'condition' => [
810 '_element_width!' => '',
811 '_position' => '',
812 ],
813 'selectors' => [
814 '{{WRAPPER}}' => 'align-self: {{VALUE}}',
815 ],
816 ]
817 );
818
819 $this->add_control(
820 '_position_description',
821 [
822 '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' ),
823 'type' => Controls_Manager::RAW_HTML,
824 'content_classes' => 'elementor-panel-alert elementor-panel-alert-warning',
825 'render_type' => 'ui',
826 'condition' => [
827 '_position!' => '',
828 ],
829 ]
830 );
831
832 $this->add_control(
833 '_position',
834 [
835 'label' => esc_html__( 'Position', 'elementor' ),
836 'type' => Controls_Manager::SELECT,
837 'default' => '',
838 'options' => [
839 '' => esc_html__( 'Default', 'elementor' ),
840 'absolute' => esc_html__( 'Absolute', 'elementor' ),
841 'fixed' => esc_html__( 'Fixed', 'elementor' ),
842 ],
843 'prefix_class' => 'elementor-',
844 'frontend_available' => true,
845 ]
846 );
847
848 $start = is_rtl() ? esc_html__( 'Right', 'elementor' ) : esc_html__( 'Left', 'elementor' );
849 $end = ! is_rtl() ? esc_html__( 'Right', 'elementor' ) : esc_html__( 'Left', 'elementor' );
850
851 $this->add_control(
852 '_offset_orientation_h',
853 [
854 'label' => esc_html__( 'Horizontal Orientation', 'elementor' ),
855 'type' => Controls_Manager::CHOOSE,
856 'toggle' => false,
857 'default' => 'start',
858 'options' => [
859 'start' => [
860 'title' => $start,
861 'icon' => 'eicon-h-align-left',
862 ],
863 'end' => [
864 'title' => $end,
865 'icon' => 'eicon-h-align-right',
866 ],
867 ],
868 'classes' => 'elementor-control-start-end',
869 'render_type' => 'ui',
870 'condition' => [
871 '_position!' => '',
872 ],
873 ]
874 );
875
876 $this->add_responsive_control(
877 '_offset_x',
878 [
879 'label' => esc_html__( 'Offset', 'elementor' ),
880 'type' => Controls_Manager::SLIDER,
881 'range' => [
882 'px' => [
883 'min' => -1000,
884 'max' => 1000,
885 'step' => 1,
886 ],
887 '%' => [
888 'min' => -200,
889 'max' => 200,
890 ],
891 'vw' => [
892 'min' => -200,
893 'max' => 200,
894 ],
895 'vh' => [
896 'min' => -200,
897 'max' => 200,
898 ],
899 ],
900 'default' => [
901 'size' => '0',
902 ],
903 'size_units' => [ 'px', '%', 'vw', 'vh' ],
904 'selectors' => [
905 'body:not(.rtl) {{WRAPPER}}' => 'left: {{SIZE}}{{UNIT}}',
906 'body.rtl {{WRAPPER}}' => 'right: {{SIZE}}{{UNIT}}',
907 ],
908 'condition' => [
909 '_offset_orientation_h!' => 'end',
910 '_position!' => '',
911 ],
912 ]
913 );
914
915 $this->add_responsive_control(
916 '_offset_x_end',
917 [
918 'label' => esc_html__( 'Offset', 'elementor' ),
919 'type' => Controls_Manager::SLIDER,
920 'range' => [
921 'px' => [
922 'min' => -1000,
923 'max' => 1000,
924 'step' => 0.1,
925 ],
926 '%' => [
927 'min' => -200,
928 'max' => 200,
929 ],
930 'vw' => [
931 'min' => -200,
932 'max' => 200,
933 ],
934 'vh' => [
935 'min' => -200,
936 'max' => 200,
937 ],
938 ],
939 'default' => [
940 'size' => '0',
941 ],
942 'size_units' => [ 'px', '%', 'vw', 'vh' ],
943 'selectors' => [
944 'body:not(.rtl) {{WRAPPER}}' => 'right: {{SIZE}}{{UNIT}}',
945 'body.rtl {{WRAPPER}}' => 'left: {{SIZE}}{{UNIT}}',
946 ],
947 'condition' => [
948 '_offset_orientation_h' => 'end',
949 '_position!' => '',
950 ],
951 ]
952 );
953
954 $this->add_control(
955 '_offset_orientation_v',
956 [
957 'label' => esc_html__( 'Vertical Orientation', 'elementor' ),
958 'type' => Controls_Manager::CHOOSE,
959 'toggle' => false,
960 'default' => 'start',
961 'options' => [
962 'start' => [
963 'title' => esc_html__( 'Top', 'elementor' ),
964 'icon' => 'eicon-v-align-top',
965 ],
966 'end' => [
967 'title' => esc_html__( 'Bottom', 'elementor' ),
968 'icon' => 'eicon-v-align-bottom',
969 ],
970 ],
971 'render_type' => 'ui',
972 'condition' => [
973 '_position!' => '',
974 ],
975 ]
976 );
977
978 $this->add_responsive_control(
979 '_offset_y',
980 [
981 'label' => esc_html__( 'Offset', 'elementor' ),
982 'type' => Controls_Manager::SLIDER,
983 'range' => [
984 'px' => [
985 'min' => -1000,
986 'max' => 1000,
987 'step' => 1,
988 ],
989 '%' => [
990 'min' => -200,
991 'max' => 200,
992 ],
993 'vh' => [
994 'min' => -200,
995 'max' => 200,
996 ],
997 'vw' => [
998 'min' => -200,
999 'max' => 200,
1000 ],
1001 ],
1002 'size_units' => [ 'px', '%', 'vh', 'vw' ],
1003 'default' => [
1004 'size' => '0',
1005 ],
1006 'selectors' => [
1007 '{{WRAPPER}}' => 'top: {{SIZE}}{{UNIT}}',
1008 ],
1009 'condition' => [
1010 '_offset_orientation_v!' => 'end',
1011 '_position!' => '',
1012 ],
1013 ]
1014 );
1015
1016 $this->add_responsive_control(
1017 '_offset_y_end',
1018 [
1019 'label' => esc_html__( 'Offset', 'elementor' ),
1020 'type' => Controls_Manager::SLIDER,
1021 'range' => [
1022 'px' => [
1023 'min' => -1000,
1024 'max' => 1000,
1025 'step' => 1,
1026 ],
1027 '%' => [
1028 'min' => -200,
1029 'max' => 200,
1030 ],
1031 'vh' => [
1032 'min' => -200,
1033 'max' => 200,
1034 ],
1035 'vw' => [
1036 'min' => -200,
1037 'max' => 200,
1038 ],
1039 ],
1040 'size_units' => [ 'px', '%', 'vh', 'vw' ],
1041 'default' => [
1042 'size' => '0',
1043 ],
1044 'selectors' => [
1045 '{{WRAPPER}}' => 'bottom: {{SIZE}}{{UNIT}}',
1046 ],
1047 'condition' => [
1048 '_offset_orientation_v' => 'end',
1049 '_position!' => '',
1050 ],
1051 ]
1052 );
1053
1054 $this->end_controls_section();
1055
1056 $this->start_controls_section(
1057 '_section_responsive',
1058 [
1059 'label' => esc_html__( 'Responsive', 'elementor' ),
1060 'tab' => Controls_Manager::TAB_ADVANCED,
1061 ]
1062 );
1063
1064 $this->add_control(
1065 'responsive_description',
1066 [
1067 'raw' => esc_html__( 'Responsive visibility will take effect only on preview or live page, and not while editing in Elementor.', 'elementor' ),
1068 'type' => Controls_Manager::RAW_HTML,
1069 'content_classes' => 'elementor-descriptor',
1070 ]
1071 );
1072
1073 $this->add_hidden_device_controls();
1074
1075 $this->end_controls_section();
1076
1077 Plugin::$instance->controls_manager->add_custom_attributes_controls( $this );
1078
1079 Plugin::$instance->controls_manager->add_custom_css_controls( $this );
1080 }
1081 }
1082