PluginProbe
Elementor Website Builder – more than just a page builder / 3.30.0-beta1
Elementor Website Builder – more than just a page builder v3.30.0-beta1
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 / icon-box.php

icon-box.php in Elementor Website Builder – more than just a page builder 3.30.0-beta1, at includes/widgets/icon-box.php

948 lines 23.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
9 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
10
11 /**
12 * Elementor icon box widget.
13 *
14 * Elementor widget that displays an icon, a headline and a text.
15 *
16 * @since 1.0.0
17 */
18 class Widget_Icon_Box extends Widget_Base {
19
20 /**
21 * Get widget name.
22 *
23 * Retrieve icon box 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 'icon-box';
32 }
33
34 /**
35 * Get widget title.
36 *
37 * Retrieve icon box widget title.
38 *
39 * @since 1.0.0
40 * @access public
41 *
42 * @return string Widget title.
43 */
44 public function get_title() {
45 return esc_html__( 'Icon Box', 'elementor' );
46 }
47
48 /**
49 * Get widget icon.
50 *
51 * Retrieve icon box widget icon.
52 *
53 * @since 1.0.0
54 * @access public
55 *
56 * @return string Widget icon.
57 */
58 public function get_icon() {
59 return 'eicon-icon-box';
60 }
61
62 /**
63 * Get widget keywords.
64 *
65 * Retrieve the list of keywords the widget belongs to.
66 *
67 * @since 2.1.0
68 * @access public
69 *
70 * @return array Widget keywords.
71 */
72 public function get_keywords() {
73 return [ 'icon box', 'icon' ];
74 }
75
76 protected function is_dynamic_content(): bool {
77 return false;
78 }
79
80 public function has_widget_inner_wrapper(): bool {
81 return ! Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
82 }
83
84 /**
85 * Get style dependencies.
86 *
87 * Retrieve the list of style dependencies the widget requires.
88 *
89 * @since 3.24.0
90 * @access public
91 *
92 * @return array Widget style dependencies.
93 */
94 public function get_style_depends(): array {
95 return [ 'widget-icon-box' ];
96 }
97
98 /**
99 * Register icon box widget controls.
100 *
101 * Adds different input fields to allow the user to change and customize the widget settings.
102 *
103 * @since 3.1.0
104 * @access protected
105 */
106 protected function register_controls() {
107 $this->start_controls_section(
108 'section_icon',
109 [
110 'label' => esc_html__( 'Icon Box', 'elementor' ),
111 ]
112 );
113
114 $this->add_control(
115 'selected_icon',
116 [
117 'label' => esc_html__( 'Icon', 'elementor' ),
118 'type' => Controls_Manager::ICONS,
119 'fa4compatibility' => 'icon',
120 'default' => [
121 'value' => 'fas fa-star',
122 'library' => 'fa-solid',
123 ],
124 ]
125 );
126
127 $this->add_control(
128 'view',
129 [
130 'label' => esc_html__( 'View', 'elementor' ),
131 'type' => Controls_Manager::SELECT,
132 'options' => [
133 'default' => esc_html__( 'Default', 'elementor' ),
134 'stacked' => esc_html__( 'Stacked', 'elementor' ),
135 'framed' => esc_html__( 'Framed', 'elementor' ),
136 ],
137 'default' => 'default',
138 'prefix_class' => 'elementor-view-',
139 'condition' => [
140 'selected_icon[value]!' => '',
141 ],
142 ]
143 );
144
145 $this->add_control(
146 'shape',
147 [
148 'label' => esc_html__( 'Shape', 'elementor' ),
149 'type' => Controls_Manager::SELECT,
150 'options' => [
151 'square' => esc_html__( 'Square', 'elementor' ),
152 'rounded' => esc_html__( 'Rounded', 'elementor' ),
153 'circle' => esc_html__( 'Circle', 'elementor' ),
154 ],
155 'default' => 'circle',
156 'condition' => [
157 'view!' => 'default',
158 'selected_icon[value]!' => '',
159 ],
160 'prefix_class' => 'elementor-shape-',
161 ]
162 );
163
164 $this->add_control(
165 'title_text',
166 [
167 'label' => esc_html__( 'Title', 'elementor' ),
168 'type' => Controls_Manager::TEXT,
169 'dynamic' => [
170 'active' => true,
171 ],
172 'default' => esc_html__( 'This is the heading', 'elementor' ),
173 'placeholder' => esc_html__( 'Enter your title', 'elementor' ),
174 'label_block' => true,
175 ]
176 );
177
178 $this->add_control(
179 'description_text',
180 [
181 'label' => esc_html__( 'Description', 'elementor' ),
182 'type' => Controls_Manager::TEXTAREA,
183 'dynamic' => [
184 'active' => true,
185 ],
186 'default' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
187 'placeholder' => esc_html__( 'Enter your description', 'elementor' ),
188 'rows' => 10,
189 ]
190 );
191
192 $this->add_control(
193 'link',
194 [
195 'label' => esc_html__( 'Link', 'elementor' ),
196 'type' => Controls_Manager::URL,
197 'dynamic' => [
198 'active' => true,
199 ],
200 'separator' => 'before',
201 ]
202 );
203
204 $this->add_control(
205 'title_size',
206 [
207 'label' => esc_html__( 'Title HTML Tag', 'elementor' ),
208 'type' => Controls_Manager::SELECT,
209 'options' => [
210 'h1' => 'H1',
211 'h2' => 'H2',
212 'h3' => 'H3',
213 'h4' => 'H4',
214 'h5' => 'H5',
215 'h6' => 'H6',
216 'div' => 'div',
217 'span' => 'span',
218 'p' => 'p',
219 ],
220 'default' => 'h3',
221 ]
222 );
223
224 $this->end_controls_section();
225
226 $this->start_controls_section(
227 'section_style_box',
228 [
229 'label' => esc_html__( 'Box', 'elementor' ),
230 'tab' => Controls_Manager::TAB_STYLE,
231 ]
232 );
233
234 $this->add_responsive_control(
235 'position',
236 [
237 'label' => esc_html__( 'Icon Position', 'elementor' ),
238 'type' => Controls_Manager::CHOOSE,
239 'default' => 'top',
240 'mobile_default' => 'top',
241 'options' => [
242 'left' => [
243 'title' => esc_html__( 'Left', 'elementor' ),
244 'icon' => 'eicon-h-align-left',
245 ],
246 'top' => [
247 'title' => esc_html__( 'Top', 'elementor' ),
248 'icon' => 'eicon-v-align-top',
249 ],
250 'right' => [
251 'title' => esc_html__( 'Right', 'elementor' ),
252 'icon' => 'eicon-h-align-right',
253 ],
254 ],
255 'prefix_class' => 'elementor%s-position-',
256 'condition' => [
257 'selected_icon[value]!' => '',
258 ],
259 ]
260 );
261
262 $this->add_responsive_control(
263 'content_vertical_alignment',
264 [
265 'label' => esc_html__( 'Vertical Alignment', 'elementor' ),
266 'type' => Controls_Manager::CHOOSE,
267 'options' => [
268 'top' => [
269 'title' => esc_html__( 'Top', 'elementor' ),
270 'icon' => 'eicon-v-align-top',
271 ],
272 'middle' => [
273 'title' => esc_html__( 'Middle', 'elementor' ),
274 'icon' => 'eicon-v-align-middle',
275 ],
276 'bottom' => [
277 'title' => esc_html__( 'Bottom', 'elementor' ),
278 'icon' => 'eicon-v-align-bottom',
279 ],
280 ],
281 'default' => 'top',
282 'toggle' => false,
283 'prefix_class' => 'elementor-vertical-align-',
284 'condition' => [
285 'position!' => 'top',
286 ],
287 ]
288 );
289
290 $this->add_responsive_control(
291 'text_align',
292 [
293 'label' => esc_html__( 'Alignment', 'elementor' ),
294 'type' => Controls_Manager::CHOOSE,
295 'options' => [
296 'left' => [
297 'title' => esc_html__( 'Left', 'elementor' ),
298 'icon' => 'eicon-text-align-left',
299 ],
300 'center' => [
301 'title' => esc_html__( 'Center', 'elementor' ),
302 'icon' => 'eicon-text-align-center',
303 ],
304 'right' => [
305 'title' => esc_html__( 'Right', 'elementor' ),
306 'icon' => 'eicon-text-align-right',
307 ],
308 'justify' => [
309 'title' => esc_html__( 'Justified', 'elementor' ),
310 'icon' => 'eicon-text-align-justify',
311 ],
312 ],
313 'selectors' => [
314 '{{WRAPPER}} .elementor-icon-box-wrapper' => 'text-align: {{VALUE}};',
315 ],
316 'separator' => 'after',
317 ]
318 );
319
320 $this->add_responsive_control(
321 'icon_space',
322 [
323 'label' => esc_html__( 'Icon Spacing', 'elementor' ),
324 'type' => Controls_Manager::SLIDER,
325 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
326 'default' => [
327 'size' => 15,
328 ],
329 'range' => [
330 'px' => [
331 'max' => 100,
332 ],
333 'em' => [
334 'max' => 10,
335 ],
336 'rem' => [
337 'max' => 10,
338 ],
339 ],
340 'selectors' => [
341 '{{WRAPPER}}' => '--icon-box-icon-margin: {{SIZE}}{{UNIT}}',
342 ],
343 'condition' => [
344 'selected_icon[value]!' => '',
345 ],
346 ]
347 );
348
349 $this->add_responsive_control(
350 'title_bottom_space',
351 [
352 'label' => esc_html__( 'Content Spacing', 'elementor' ),
353 'type' => Controls_Manager::SLIDER,
354 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
355 'range' => [
356 'px' => [
357 'max' => 100,
358 ],
359 'em' => [
360 'min' => 0,
361 'max' => 10,
362 ],
363 'rem' => [
364 'min' => 0,
365 'max' => 10,
366 ],
367 ],
368 'selectors' => [
369 '{{WRAPPER}} .elementor-icon-box-title' => 'margin-bottom: {{SIZE}}{{UNIT}};',
370 ],
371 ]
372 );
373
374 $this->end_controls_section();
375
376 $this->start_controls_section(
377 'section_style_icon',
378 [
379 'label' => esc_html__( 'Icon', 'elementor' ),
380 'tab' => Controls_Manager::TAB_STYLE,
381 'condition' => [
382 'selected_icon[value]!' => '',
383 ],
384 ]
385 );
386
387 $this->start_controls_tabs( 'icon_colors' );
388
389 $this->start_controls_tab(
390 'icon_colors_normal',
391 [
392 'label' => esc_html__( 'Normal', 'elementor' ),
393 ]
394 );
395
396 $this->add_control(
397 'primary_color',
398 [
399 'label' => esc_html__( 'Primary Color', 'elementor' ),
400 'type' => Controls_Manager::COLOR,
401 'global' => [
402 'default' => Global_Colors::COLOR_PRIMARY,
403 ],
404 'default' => '',
405 'selectors' => [
406 '{{WRAPPER}}.elementor-view-stacked .elementor-icon' => 'background-color: {{VALUE}};',
407 '{{WRAPPER}}.elementor-view-framed .elementor-icon, {{WRAPPER}}.elementor-view-default .elementor-icon' => 'fill: {{VALUE}}; color: {{VALUE}}; border-color: {{VALUE}};',
408 ],
409 ]
410 );
411
412 $this->add_control(
413 'secondary_color',
414 [
415 'label' => esc_html__( 'Secondary Color', 'elementor' ),
416 'type' => Controls_Manager::COLOR,
417 'default' => '',
418 'condition' => [
419 'view!' => 'default',
420 ],
421 'selectors' => [
422 '{{WRAPPER}}.elementor-view-framed .elementor-icon' => 'background-color: {{VALUE}};',
423 '{{WRAPPER}}.elementor-view-stacked .elementor-icon' => 'fill: {{VALUE}}; color: {{VALUE}};',
424 ],
425 ]
426 );
427
428 $this->end_controls_tab();
429
430 $this->start_controls_tab(
431 'icon_colors_hover',
432 [
433 'label' => esc_html__( 'Hover', 'elementor' ),
434 ]
435 );
436
437 $this->add_control(
438 'hover_primary_color',
439 [
440 'label' => esc_html__( 'Primary Color', 'elementor' ),
441 'type' => Controls_Manager::COLOR,
442 'default' => '',
443 'selectors' => [
444 '{{WRAPPER}}.elementor-view-stacked:has(:hover) .elementor-icon,
445 {{WRAPPER}}.elementor-view-stacked:has(:focus) .elementor-icon' => 'background-color: {{VALUE}};',
446 '{{WRAPPER}}.elementor-view-framed:has(:hover) .elementor-icon,
447 {{WRAPPER}}.elementor-view-default:has(:hover) .elementor-icon,
448 {{WRAPPER}}.elementor-view-framed:has(:focus) .elementor-icon,
449 {{WRAPPER}}.elementor-view-default:has(:focus) .elementor-icon' => 'fill: {{VALUE}}; color: {{VALUE}}; border-color: {{VALUE}};',
450 ],
451 ]
452 );
453
454 $this->add_control(
455 'hover_secondary_color',
456 [
457 'label' => esc_html__( 'Secondary Color', 'elementor' ),
458 'type' => Controls_Manager::COLOR,
459 'default' => '',
460 'condition' => [
461 'view!' => 'default',
462 ],
463 'selectors' => [
464 '{{WRAPPER}}.elementor-view-framed:has(:hover) .elementor-icon,
465 {{WRAPPER}}.elementor-view-framed:has(:focus) .elementor-icon' => 'background-color: {{VALUE}};',
466 '{{WRAPPER}}.elementor-view-stacked:has(:hover) .elementor-icon,
467 {{WRAPPER}}.elementor-view-stacked:has(:focus) .elementor-icon' => 'fill: {{VALUE}}; color: {{VALUE}};',
468 ],
469 ]
470 );
471
472 $this->add_control(
473 'hover_icon_colors_transition_duration',
474 [
475 'label' => esc_html__( 'Transition Duration', 'elementor' ),
476 'type' => Controls_Manager::SLIDER,
477 'size_units' => [ 's', 'ms', 'custom' ],
478 'default' => [
479 'unit' => 's',
480 ],
481 'selectors' => [
482 '{{WRAPPER}} .elementor-icon' => 'transition-duration: {{SIZE}}{{UNIT}};',
483 ],
484 ]
485 );
486
487 $this->add_control(
488 'hover_animation',
489 [
490 'label' => esc_html__( 'Hover Animation', 'elementor' ),
491 'type' => Controls_Manager::HOVER_ANIMATION,
492 ]
493 );
494
495 $this->end_controls_tab();
496
497 $this->end_controls_tabs();
498
499 $this->add_responsive_control(
500 'icon_size',
501 [
502 'label' => esc_html__( 'Size', 'elementor' ),
503 'type' => Controls_Manager::SLIDER,
504 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
505 'range' => [
506 'px' => [
507 'min' => 6,
508 'max' => 300,
509 ],
510 ],
511 'selectors' => [
512 '{{WRAPPER}} .elementor-icon' => 'font-size: {{SIZE}}{{UNIT}};',
513 ],
514 ]
515 );
516
517 $this->add_responsive_control(
518 'icon_padding',
519 [
520 'label' => esc_html__( 'Padding', 'elementor' ),
521 'type' => Controls_Manager::SLIDER,
522 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
523 'selectors' => [
524 '{{WRAPPER}} .elementor-icon' => 'padding: {{SIZE}}{{UNIT}};',
525 ],
526 'range' => [
527 'px' => [
528 'max' => 50,
529 ],
530 'em' => [
531 'min' => 0,
532 'max' => 5,
533 ],
534 'rem' => [
535 'min' => 0,
536 'max' => 5,
537 ],
538 ],
539 'condition' => [
540 'view!' => 'default',
541 ],
542 ]
543 );
544
545 $active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
546
547 $rotate_device_args = [];
548
549 $rotate_device_settings = [
550 'default' => [
551 'unit' => 'deg',
552 ],
553 ];
554
555 foreach ( $active_breakpoints as $breakpoint_name => $breakpoint ) {
556 $rotate_device_args[ $breakpoint_name ] = $rotate_device_settings;
557 }
558
559 $this->add_responsive_control(
560 'rotate',
561 [
562 'label' => esc_html__( 'Rotate', 'elementor' ),
563 'type' => Controls_Manager::SLIDER,
564 'size_units' => [ 'deg', 'grad', 'rad', 'turn', 'custom' ],
565 'default' => [
566 'unit' => 'deg',
567 ],
568 'tablet_default' => [
569 'unit' => 'deg',
570 ],
571 'mobile_default' => [
572 'unit' => 'deg',
573 ],
574 'device_args' => $rotate_device_args,
575 'selectors' => [
576 '{{WRAPPER}} .elementor-icon i' => 'transform: rotate({{SIZE}}{{UNIT}});',
577 ],
578 ]
579 );
580
581 $this->add_responsive_control(
582 'border_width',
583 [
584 'label' => esc_html__( 'Border Width', 'elementor' ),
585 'type' => Controls_Manager::DIMENSIONS,
586 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
587 'selectors' => [
588 '{{WRAPPER}} .elementor-icon' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
589 ],
590 'condition' => [
591 'view' => 'framed',
592 ],
593 ]
594 );
595
596 $this->add_responsive_control(
597 'border_radius',
598 [
599 'label' => esc_html__( 'Border Radius', 'elementor' ),
600 'type' => Controls_Manager::DIMENSIONS,
601 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
602 'selectors' => [
603 '{{WRAPPER}} .elementor-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
604 ],
605 'condition' => [
606 'view!' => 'default',
607 ],
608 'separator' => 'before',
609 ]
610 );
611
612 $this->end_controls_section();
613
614 $this->start_controls_section(
615 'section_style_content',
616 [
617 'label' => esc_html__( 'Content', 'elementor' ),
618 'tab' => Controls_Manager::TAB_STYLE,
619 ]
620 );
621
622 $this->add_control(
623 'heading_title',
624 [
625 'label' => esc_html__( 'Title', 'elementor' ),
626 'type' => Controls_Manager::HEADING,
627 'separator' => 'before',
628 ]
629 );
630
631 $this->add_group_control(
632 Group_Control_Typography::get_type(),
633 [
634 'name' => 'title_typography',
635 'selector' => '{{WRAPPER}} .elementor-icon-box-title, {{WRAPPER}} .elementor-icon-box-title a',
636 'global' => [
637 'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
638 ],
639 ]
640 );
641
642 $this->add_group_control(
643 Group_Control_Text_Stroke::get_type(),
644 [
645 'name' => 'text_stroke',
646 'selector' => '{{WRAPPER}} .elementor-icon-box-title',
647 ]
648 );
649
650 $this->add_group_control(
651 Group_Control_Text_Shadow::get_type(),
652 [
653 'name' => 'title_shadow',
654 'selector' => '{{WRAPPER}} .elementor-icon-box-title',
655 ]
656 );
657
658 $this->start_controls_tabs( 'icon_box_title_colors' );
659
660 $this->start_controls_tab(
661 'icon_box_title_colors_normal',
662 [
663 'label' => esc_html__( 'Normal', 'elementor' ),
664 ]
665 );
666
667 $this->add_control(
668 'title_color',
669 [
670 'label' => esc_html__( 'Color', 'elementor' ),
671 'type' => Controls_Manager::COLOR,
672 'default' => '',
673 'selectors' => [
674 '{{WRAPPER}} .elementor-icon-box-title' => 'color: {{VALUE}};',
675 ],
676 'global' => [
677 'default' => Global_Colors::COLOR_PRIMARY,
678 ],
679 ]
680 );
681
682 $this->end_controls_tab();
683
684 $this->start_controls_tab(
685 'icon_box_title_colors_hover',
686 [
687 'label' => esc_html__( 'Hover', 'elementor' ),
688 ]
689 );
690
691 $this->add_control(
692 'hover_title_color',
693 [
694 'label' => esc_html__( 'Color', 'elementor' ),
695 'type' => Controls_Manager::COLOR,
696 'default' => '',
697 'selectors' => [
698 '{{WRAPPER}}:has(:hover) .elementor-icon-box-title,
699 {{WRAPPER}}:has(:focus) .elementor-icon-box-title' => 'color: {{VALUE}};',
700 ],
701 'global' => [
702 'default' => Global_Colors::COLOR_PRIMARY,
703 ],
704 ]
705 );
706
707 $this->add_control(
708 'hover_title_color_transition_duration',
709 [
710 'label' => esc_html__( 'Transition Duration', 'elementor' ),
711 'type' => Controls_Manager::SLIDER,
712 'size_units' => [ 's', 'ms', 'custom' ],
713 'default' => [
714 'unit' => 's',
715 ],
716 'selectors' => [
717 '{{WRAPPER}} .elementor-icon-box-title' => 'transition-duration: {{SIZE}}{{UNIT}};',
718 ],
719 ]
720 );
721
722 $this->end_controls_tab();
723
724 $this->end_controls_tabs();
725
726 $this->add_control(
727 'heading_description',
728 [
729 'label' => esc_html__( 'Description', 'elementor' ),
730 'type' => Controls_Manager::HEADING,
731 'separator' => 'before',
732 ]
733 );
734
735 $this->add_group_control(
736 Group_Control_Typography::get_type(),
737 [
738 'name' => 'description_typography',
739 'selector' => '{{WRAPPER}} .elementor-icon-box-description',
740 'global' => [
741 'default' => Global_Typography::TYPOGRAPHY_TEXT,
742 ],
743 ]
744 );
745
746 $this->add_group_control(
747 Group_Control_Text_Shadow::get_type(),
748 [
749 'name' => 'description_shadow',
750 'selector' => '{{WRAPPER}} .elementor-icon-box-description',
751 ]
752 );
753
754 $this->add_control(
755 'description_color',
756 [
757 'label' => esc_html__( 'Color', 'elementor' ),
758 'type' => Controls_Manager::COLOR,
759 'default' => '',
760 'selectors' => [
761 '{{WRAPPER}} .elementor-icon-box-description' => 'color: {{VALUE}};',
762 ],
763 'global' => [
764 'default' => Global_Colors::COLOR_TEXT,
765 ],
766 ]
767 );
768
769 $this->end_controls_section();
770 }
771
772 /**
773 * Render icon box widget output on the frontend.
774 *
775 * Written in PHP and used to generate the final HTML.
776 *
777 * @since 1.0.0
778 * @access protected
779 */
780 protected function render() {
781 $settings = $this->get_settings_for_display();
782 $has_link = ! empty( $settings['link']['url'] );
783 $html_tag = $has_link ? 'a' : 'span';
784
785 $this->add_render_attribute( 'icon', 'class', 'elementor-icon' );
786
787 if ( ! empty( $settings['hover_animation'] ) ) {
788 $this->add_render_attribute( 'icon', 'class', 'elementor-animation-' . $settings['hover_animation'] );
789 }
790
791 $has_icon = ! empty( $settings['selected_icon']['value'] );
792 $has_content = ! Utils::is_empty( $settings['title_text'] ) || ! Utils::is_empty( $settings['description_text'] );
793
794 if ( ! $has_icon && ! $has_content ) {
795 return;
796 }
797
798 if ( $has_link ) {
799 $this->add_link_attributes( 'link', $settings['link'] );
800 $this->add_render_attribute( 'icon', 'tabindex', '-1' );
801 if ( ! empty( $settings['title_text'] ) ) {
802 $this->add_render_attribute( 'icon', 'aria-label', $settings['title_text'] );
803 }
804 }
805
806 if ( ! isset( $settings['icon'] ) && ! Icons_Manager::is_migration_allowed() ) {
807 // add old default
808 $settings['icon'] = 'fa fa-star';
809 }
810
811 if ( ! empty( $settings['icon'] ) ) {
812 $this->add_render_attribute( 'i', 'class', $settings['icon'] );
813 $this->add_render_attribute( 'i', 'aria-hidden', 'true' );
814 }
815
816 $this->add_render_attribute( 'description_text', 'class', 'elementor-icon-box-description' );
817
818 $this->add_inline_editing_attributes( 'title_text', 'none' );
819 $this->add_inline_editing_attributes( 'description_text' );
820
821 $migrated = isset( $settings['__fa4_migrated']['selected_icon'] );
822 $is_new = ! isset( $settings['icon'] ) && Icons_Manager::is_migration_allowed();
823 ?>
824 <div class="elementor-icon-box-wrapper">
825
826 <?php if ( $has_icon ) : ?>
827 <div class="elementor-icon-box-icon">
828 <<?php Utils::print_validated_html_tag( $html_tag ); ?> <?php $this->print_render_attribute_string( 'link' ); ?> <?php $this->print_render_attribute_string( 'icon' ); ?>>
829 <?php
830 if ( $is_new || $migrated ) {
831 Icons_Manager::render_icon( $settings['selected_icon'], [ 'aria-hidden' => 'true' ] );
832 } elseif ( ! empty( $settings['icon'] ) ) {
833 ?><i <?php $this->print_render_attribute_string( 'i' ); ?>></i><?php
834 }
835 ?>
836 </<?php Utils::print_validated_html_tag( $html_tag ); ?>>
837 </div>
838 <?php endif; ?>
839
840 <?php if ( $has_content ) : ?>
841 <div class="elementor-icon-box-content">
842
843 <?php if ( ! Utils::is_empty( $settings['title_text'] ) ) : ?>
844 <<?php Utils::print_validated_html_tag( $settings['title_size'] ); ?> class="elementor-icon-box-title">
845 <<?php Utils::print_validated_html_tag( $html_tag ); ?> <?php $this->print_render_attribute_string( 'link' ); ?> <?php $this->print_render_attribute_string( 'title_text' ); ?>>
846 <?php $this->print_unescaped_setting( 'title_text' ); ?>
847 </<?php Utils::print_validated_html_tag( $html_tag ); ?>>
848 </<?php Utils::print_validated_html_tag( $settings['title_size'] ); ?>>
849 <?php endif; ?>
850
851 <?php if ( ! Utils::is_empty( $settings['description_text'] ) ) : ?>
852 <p <?php $this->print_render_attribute_string( 'description_text' ); ?>>
853 <?php $this->print_unescaped_setting( 'description_text' ); ?>
854 </p>
855 <?php endif; ?>
856
857 </div>
858 <?php endif; ?>
859
860 </div>
861 <?php
862 }
863
864 /**
865 * Render icon box widget output in the editor.
866 *
867 * Written as a Backbone JavaScript template and used to generate the live preview.
868 *
869 * @since 2.9.0
870 * @access protected
871 */
872 protected function content_template() {
873 ?>
874 <#
875 // For older version `settings.icon` is needed.
876 var hasIcon = settings.icon || settings.selected_icon.value;
877 var hasContent = settings.title_text || settings.description_text;
878
879 if ( ! hasIcon && ! hasContent ) {
880 return;
881 }
882
883 var hasLink = settings.link.url,
884 htmlTag = hasLink ? 'a' : 'span',
885 iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, { 'aria-hidden': true }, 'i' , 'object' ),
886 migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' ),
887 titleSizeTag = elementor.helpers.validateHTMLTag( settings.title_size );
888
889 view.addRenderAttribute( 'icon', 'class', 'elementor-icon' );
890
891 if ( '' !== settings.hover_animation ) {
892 view.addRenderAttribute( 'icon', 'class', 'elementor-animation-' + settings.hover_animation );
893 }
894
895 if ( hasLink ) {
896 view.addRenderAttribute( 'link', 'href', elementor.helpers.sanitizeUrl( settings.link.url ) );
897 view.addRenderAttribute( 'icon', 'tabindex', '-1' );
898 if ( '' !== settings.title_text ) {
899 view.addRenderAttribute( 'icon', 'aria-label', settings.title_text );
900 }
901 }
902
903 view.addRenderAttribute( 'description_text', 'class', 'elementor-icon-box-description' );
904
905 view.addInlineEditingAttributes( 'title_text', 'none' );
906 view.addInlineEditingAttributes( 'description_text' );
907 #>
908 <div class="elementor-icon-box-wrapper">
909
910 <# if ( hasIcon ) { #>
911 <div class="elementor-icon-box-icon">
912 <{{{ htmlTag }}} {{{ view.getRenderAttributeString( 'link' ) }}} {{{ view.getRenderAttributeString( 'icon' ) }}}>
913 <# if ( iconHTML && iconHTML.rendered && ( ! settings.icon || migrated ) ) { #>
914 {{{ elementor.helpers.sanitize( iconHTML.value ) }}}
915 <# } else { #>
916 <i class="{{ _.escape( settings.icon ) }}" aria-hidden="true"></i>
917 <# } #>
918 </{{{ htmlTag }}}>
919 </div>
920 <# } #>
921
922 <# if ( hasContent ) { #>
923 <div class="elementor-icon-box-content">
924
925 <# if ( settings.title_text ) { #>
926 <{{{ titleSizeTag }}} class="elementor-icon-box-title">
927 <{{{ htmlTag }}} {{{ view.getRenderAttributeString( 'link' ) }}} {{{ view.getRenderAttributeString( 'title_text' ) }}}>
928 {{{ elementor.helpers.sanitize( settings.title_text ) }}}
929 </{{{ htmlTag }}}>
930 </{{{ titleSizeTag }}}>
931 <# } #>
932
933 <# if ( settings.description_text ) { #>
934 <p {{{ view.getRenderAttributeString( 'description_text' ) }}}>{{{ elementor.helpers.sanitize( settings.description_text ) }}}</p>
935 <# } #>
936
937 </div>
938 <# } #>
939
940 </div>
941 <?php
942 }
943
944 public function on_import( $element ) {
945 return Icons_Manager::on_import_migration( $element, 'icon', 'selected_icon', true );
946 }
947 }
948