first commit

This commit is contained in:
2024-07-15 11:28:08 +02:00
commit f52d538ea5
21891 changed files with 6161164 additions and 0 deletions

View File

@@ -0,0 +1,663 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor accordion widget.
*
* Elementor widget that displays a collapsible display of content in an
* accordion style, showing only one item at a time.
*
* @since 1.0.0
*/
class Widget_Accordion extends Widget_Base {
/**
* Get widget name.
*
* Retrieve accordion widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'accordion';
}
/**
* Get widget title.
*
* Retrieve accordion widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Accordion', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve accordion widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-accordion';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'accordion', 'tabs', 'toggle' ];
}
/**
* Register accordion widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_title',
[
'label' => __( 'Accordion', 'elementor' ),
]
);
$repeater = new Repeater();
$repeater->add_control(
'tab_title',
[
'label' => __( 'Title & Description', 'elementor' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Accordion Title', 'elementor' ),
'dynamic' => [
'active' => true,
],
'label_block' => true,
]
);
$repeater->add_control(
'tab_content',
[
'label' => __( 'Content', 'elementor' ),
'type' => Controls_Manager::WYSIWYG,
'default' => __( 'Accordion Content', 'elementor' ),
'show_label' => false,
]
);
$this->add_control(
'tabs',
[
'label' => __( 'Accordion Items', 'elementor' ),
'type' => Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'default' => [
[
'tab_title' => __( 'Accordion #1', 'elementor' ),
'tab_content' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
],
[
'tab_title' => __( 'Accordion #2', 'elementor' ),
'tab_content' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
],
],
'title_field' => '{{{ tab_title }}}',
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->add_control(
'selected_icon',
[
'label' => __( 'Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'separator' => 'before',
'fa4compatibility' => 'icon',
'default' => [
'value' => 'fas fa-plus',
'library' => 'fa-solid',
],
'recommended' => [
'fa-solid' => [
'chevron-down',
'angle-down',
'angle-double-down',
'caret-down',
'caret-square-down',
],
'fa-regular' => [
'caret-square-down',
],
],
'skin' => 'inline',
'label_block' => false,
]
);
$this->add_control(
'selected_active_icon',
[
'label' => __( 'Active Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'fa4compatibility' => 'icon_active',
'default' => [
'value' => 'fas fa-minus',
'library' => 'fa-solid',
],
'recommended' => [
'fa-solid' => [
'chevron-up',
'angle-up',
'angle-double-up',
'caret-up',
'caret-square-up',
],
'fa-regular' => [
'caret-square-up',
],
],
'skin' => 'inline',
'label_block' => false,
'condition' => [
'selected_icon[value]!' => '',
],
]
);
$this->add_control(
'title_html_tag',
[
'label' => __( 'Title HTML Tag', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'h1' => 'H1',
'h2' => 'H2',
'h3' => 'H3',
'h4' => 'H4',
'h5' => 'H5',
'h6' => 'H6',
'div' => 'div',
],
'default' => 'div',
'separator' => 'before',
]
);
$this->add_control(
'faq_schema',
[
'label' => __( 'FAQ Schema', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'separator' => 'before',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_title_style',
[
'label' => __( 'Accordion', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'border_width',
[
'label' => __( 'Border Width', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 10,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-accordion-item' => 'border-width: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .elementor-accordion-item .elementor-tab-content' => 'border-width: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .elementor-accordion-item .elementor-tab-title.elementor-active' => 'border-width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'border_color',
[
'label' => __( 'Border Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-accordion-item' => 'border-color: {{VALUE}};',
'{{WRAPPER}} .elementor-accordion-item .elementor-tab-content' => 'border-top-color: {{VALUE}};',
'{{WRAPPER}} .elementor-accordion-item .elementor-tab-title.elementor-active' => 'border-bottom-color: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_toggle_style_title',
[
'label' => __( 'Title', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'title_background',
[
'label' => __( 'Background', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-title' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-accordion-icon, {{WRAPPER}} .elementor-accordion-title' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
]
);
$this->add_control(
'tab_active_color',
[
'label' => __( 'Active Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-active .elementor-accordion-icon, {{WRAPPER}} .elementor-active .elementor-accordion-title' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_ACCENT,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'selector' => '{{WRAPPER}} .elementor-accordion-title',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'title_shadow',
'selector' => '{{WRAPPER}} .elementor-accordion-title',
]
);
$this->add_responsive_control(
'title_padding',
[
'label' => __( 'Padding', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-tab-title' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_toggle_style_icon',
[
'label' => __( 'Icon', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'selected_icon[value]!' => '',
],
]
);
$this->add_control(
'icon_align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Start', 'elementor' ),
'icon' => 'eicon-h-align-left',
],
'right' => [
'title' => __( 'End', 'elementor' ),
'icon' => 'eicon-h-align-right',
],
],
'default' => is_rtl() ? 'right' : 'left',
'toggle' => false,
]
);
$this->add_control(
'icon_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-title .elementor-accordion-icon i:before' => 'color: {{VALUE}};',
'{{WRAPPER}} .elementor-tab-title .elementor-accordion-icon svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_control(
'icon_active_color',
[
'label' => __( 'Active Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-title.elementor-active .elementor-accordion-icon i:before' => 'color: {{VALUE}};',
'{{WRAPPER}} .elementor-tab-title.elementor-active .elementor-accordion-icon svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'icon_space',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-accordion-icon.elementor-accordion-icon-left' => 'margin-right: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .elementor-accordion-icon.elementor-accordion-icon-right' => 'margin-left: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_toggle_style_content',
[
'label' => __( 'Content', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'content_background_color',
[
'label' => __( 'Background', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-content' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'content_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-content' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'content_typography',
'selector' => '{{WRAPPER}} .elementor-tab-content',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'content_shadow',
'selector' => '{{WRAPPER}} .elementor-tab-content',
]
);
$this->add_responsive_control(
'content_padding',
[
'label' => __( 'Padding', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-tab-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
}
/**
* Render accordion widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$migrated = isset( $settings['__fa4_migrated']['selected_icon'] );
if ( ! isset( $settings['icon'] ) && ! Icons_Manager::is_migration_allowed() ) {
// @todo: remove when deprecated
// added as bc in 2.6
// add old default
$settings['icon'] = 'fa fa-plus';
$settings['icon_active'] = 'fa fa-minus';
$settings['icon_align'] = $this->get_settings( 'icon_align' );
}
$is_new = empty( $settings['icon'] ) && Icons_Manager::is_migration_allowed();
$has_icon = ( ! $is_new || ! empty( $settings['selected_icon']['value'] ) );
$id_int = substr( $this->get_id_int(), 0, 3 );
?>
<div class="elementor-accordion" role="tablist">
<?php
foreach ( $settings['tabs'] as $index => $item ) :
$tab_count = $index + 1;
$tab_title_setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $index );
$tab_content_setting_key = $this->get_repeater_setting_key( 'tab_content', 'tabs', $index );
$this->add_render_attribute( $tab_title_setting_key, [
'id' => 'elementor-tab-title-' . $id_int . $tab_count,
'class' => [ 'elementor-tab-title' ],
'data-tab' => $tab_count,
'role' => 'tab',
'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
'aria-expanded' => 'false',
] );
$this->add_render_attribute( $tab_content_setting_key, [
'id' => 'elementor-tab-content-' . $id_int . $tab_count,
'class' => [ 'elementor-tab-content', 'elementor-clearfix' ],
'data-tab' => $tab_count,
'role' => 'tabpanel',
'aria-labelledby' => 'elementor-tab-title-' . $id_int . $tab_count,
] );
$this->add_inline_editing_attributes( $tab_content_setting_key, 'advanced' );
?>
<div class="elementor-accordion-item">
<<?php echo Utils::validate_html_tag( $settings['title_html_tag'] ); ?> <?php echo $this->get_render_attribute_string( $tab_title_setting_key ); ?>>
<?php if ( $has_icon ) : ?>
<span class="elementor-accordion-icon elementor-accordion-icon-<?php echo esc_attr( $settings['icon_align'] ); ?>" aria-hidden="true">
<?php
if ( $is_new || $migrated ) { ?>
<span class="elementor-accordion-icon-closed"><?php Icons_Manager::render_icon( $settings['selected_icon'] ); ?></span>
<span class="elementor-accordion-icon-opened"><?php Icons_Manager::render_icon( $settings['selected_active_icon'] ); ?></span>
<?php } else { ?>
<i class="elementor-accordion-icon-closed <?php echo esc_attr( $settings['icon'] ); ?>"></i>
<i class="elementor-accordion-icon-opened <?php echo esc_attr( $settings['icon_active'] ); ?>"></i>
<?php } ?>
</span>
<?php endif; ?>
<a class="elementor-accordion-title" href=""><?php echo $item['tab_title']; ?></a>
</<?php echo Utils::validate_html_tag( $settings['title_html_tag'] ); ?>>
<div <?php echo $this->get_render_attribute_string( $tab_content_setting_key ); ?>><?php echo $this->parse_text_editor( $item['tab_content'] ); ?></div>
</div>
<?php endforeach; ?>
<?php
if ( isset( $settings['faq_schema'] ) && 'yes' === $settings['faq_schema'] ) {
$json = [
'@context' => 'https://schema.org',
'@type' => 'FAQPage',
'mainEntity' => [],
];
foreach ( $settings['tabs'] as $index => $item ) {
$json['mainEntity'][] = [
'@type' => 'Question',
'name' => wp_strip_all_tags( $item['tab_title'] ),
'acceptedAnswer' => [
'@type' => 'Answer',
'text' => $this->parse_text_editor( $item['tab_content'] ),
],
];
}
?>
<script type="application/ld+json"><?php echo wp_json_encode( $json ); ?></script>
<?php } ?>
</div>
<?php
}
/**
* Render accordion widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<div class="elementor-accordion" role="tablist">
<#
if ( settings.tabs ) {
var tabindex = view.getIDInt().toString().substr( 0, 3 ),
iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, {}, 'i' , 'object' ),
iconActiveHTML = elementor.helpers.renderIcon( view, settings.selected_active_icon, {}, 'i' , 'object' ),
migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' );
_.each( settings.tabs, function( item, index ) {
var tabCount = index + 1,
tabTitleKey = view.getRepeaterSettingKey( 'tab_title', 'tabs', index ),
tabContentKey = view.getRepeaterSettingKey( 'tab_content', 'tabs', index );
view.addRenderAttribute( tabTitleKey, {
'id': 'elementor-tab-title-' + tabindex + tabCount,
'class': [ 'elementor-tab-title' ],
'tabindex': tabindex + tabCount,
'data-tab': tabCount,
'role': 'tab',
'aria-controls': 'elementor-tab-content-' + tabindex + tabCount,
'aria-expanded': 'false',
} );
view.addRenderAttribute( tabContentKey, {
'id': 'elementor-tab-content-' + tabindex + tabCount,
'class': [ 'elementor-tab-content', 'elementor-clearfix' ],
'data-tab': tabCount,
'role': 'tabpanel',
'aria-labelledby': 'elementor-tab-title-' + tabindex + tabCount
} );
view.addInlineEditingAttributes( tabContentKey, 'advanced' );
var titleHTMLTag = elementor.helpers.validateHTMLTag( settings.title_html_tag );
#>
<div class="elementor-accordion-item">
<{{{ titleHTMLTag }}} {{{ view.getRenderAttributeString( tabTitleKey ) }}}>
<# if ( settings.icon || settings.selected_icon ) { #>
<span class="elementor-accordion-icon elementor-accordion-icon-{{ settings.icon_align }}" aria-hidden="true">
<# if ( iconHTML && iconHTML.rendered && ( ! settings.icon || migrated ) ) { #>
<span class="elementor-accordion-icon-closed">{{{ iconHTML.value }}}</span>
<span class="elementor-accordion-icon-opened">{{{ iconActiveHTML.value }}}</span>
<# } else { #>
<i class="elementor-accordion-icon-closed {{ settings.icon }}"></i>
<i class="elementor-accordion-icon-opened {{ settings.icon_active }}"></i>
<# } #>
</span>
<# } #>
<a class="elementor-accordion-title" href="">{{{ item.tab_title }}}</a>
</{{{ titleHTMLTag }}}>
<div {{{ view.getRenderAttributeString( tabContentKey ) }}}>{{{ item.tab_content }}}</div>
</div>
<#
} );
} #>
</div>
<?php
}
}

View File

@@ -0,0 +1,369 @@
<?php
namespace Elementor;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor alert widget.
*
* Elementor widget that displays a collapsible display of content in an toggle
* style, allowing the user to open multiple items.
*
* @since 1.0.0
*/
class Widget_Alert extends Widget_Base {
/**
* Get widget name.
*
* Retrieve alert widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'alert';
}
/**
* Get widget title.
*
* Retrieve alert widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Alert', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve alert widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-alert';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'alert', 'notice', 'message' ];
}
/**
* Register alert widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_alert',
[
'label' => __( 'Alert', 'elementor' ),
]
);
$this->add_control(
'alert_type',
[
'label' => __( 'Type', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'info',
'options' => [
'info' => __( 'Info', 'elementor' ),
'success' => __( 'Success', 'elementor' ),
'warning' => __( 'Warning', 'elementor' ),
'danger' => __( 'Danger', 'elementor' ),
],
'style_transfer' => true,
]
);
$this->add_control(
'alert_title',
[
'label' => __( 'Title & Description', 'elementor' ),
'type' => Controls_Manager::TEXT,
'placeholder' => __( 'Enter your title', 'elementor' ),
'default' => __( 'This is an Alert', 'elementor' ),
'label_block' => true,
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'alert_description',
[
'label' => __( 'Content', 'elementor' ),
'type' => Controls_Manager::TEXTAREA,
'placeholder' => __( 'Enter your description', 'elementor' ),
'default' => __( 'I am a description. Click the edit button to change this text.', 'elementor' ),
'separator' => 'none',
'show_label' => false,
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'show_dismiss',
[
'label' => __( 'Dismiss Button', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'show',
'options' => [
'show' => __( 'Show', 'elementor' ),
'hide' => __( 'Hide', 'elementor' ),
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_type',
[
'label' => __( 'Alert', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'background',
[
'label' => __( 'Background Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-alert' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'border_color',
[
'label' => __( 'Border Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-alert' => 'border-color: {{VALUE}};',
],
]
);
$this->add_control(
'border_left-width',
[
'label' => __( 'Left Border Width', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-alert' => 'border-left-width: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_title',
[
'label' => __( 'Title', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-alert-title' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'alert_title',
'selector' => '{{WRAPPER}} .elementor-alert-title',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'title_shadow',
'selector' => '{{WRAPPER}} .elementor-alert-title',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_description',
[
'label' => __( 'Description', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'description_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-alert-description' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'alert_description',
'selector' => '{{WRAPPER}} .elementor-alert-description',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'description_shadow',
'selector' => '{{WRAPPER}} .elementor-alert-description',
]
);
$this->end_controls_section();
}
/**
* Render alert widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
if ( Utils::is_empty( $settings['alert_title'] ) ) {
return;
}
if ( ! empty( $settings['alert_type'] ) ) {
$this->add_render_attribute( 'wrapper', 'class', 'elementor-alert elementor-alert-' . $settings['alert_type'] );
}
$this->add_render_attribute( 'wrapper', 'role', 'alert' );
$this->add_render_attribute( 'alert_title', 'class', 'elementor-alert-title' );
$this->add_inline_editing_attributes( 'alert_title', 'none' );
?>
<div <?php echo $this->get_render_attribute_string( 'wrapper' ); ?>>
<span <?php echo $this->get_render_attribute_string( 'alert_title' ); ?>><?php echo $settings['alert_title']; ?></span>
<?php
if ( ! Utils::is_empty( $settings['alert_description'] ) ) :
$this->add_render_attribute( 'alert_description', 'class', 'elementor-alert-description' );
$this->add_inline_editing_attributes( 'alert_description' );
?>
<span <?php echo $this->get_render_attribute_string( 'alert_description' ); ?>><?php echo $settings['alert_description']; ?></span>
<?php endif; ?>
<?php if ( 'show' === $settings['show_dismiss'] ) : ?>
<button type="button" class="elementor-alert-dismiss">
<span aria-hidden="true">&times;</span>
<span class="elementor-screen-only"><?php echo __( 'Dismiss alert', 'elementor' ); ?></span>
</button>
<?php endif; ?>
</div>
<?php
}
/**
* Render alert widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<# if ( settings.alert_title ) {
view.addRenderAttribute( {
alert_title: { class: 'elementor-alert-title' },
alert_description: { class: 'elementor-alert-description' }
} );
view.addInlineEditingAttributes( 'alert_title', 'none' );
view.addInlineEditingAttributes( 'alert_description' );
#>
<div class="elementor-alert elementor-alert-{{ settings.alert_type }}" role="alert">
<span {{{ view.getRenderAttributeString( 'alert_title' ) }}}>{{{ settings.alert_title }}}</span>
<span {{{ view.getRenderAttributeString( 'alert_description' ) }}}>{{{ settings.alert_description }}}</span>
<# if ( 'show' === settings.show_dismiss ) { #>
<button type="button" class="elementor-alert-dismiss">
<span aria-hidden="true">&times;</span>
<span class="elementor-screen-only"><?php echo __( 'Dismiss alert', 'elementor' ); ?></span>
</button>
<# } #>
</div>
<# } #>
<?php
}
}

View File

@@ -0,0 +1,347 @@
<?php
namespace Elementor;
use Elementor\Modules\DynamicTags\Module as TagsModule;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor audio widget.
*
* Elementor widget that displays an audio player.
*
* @since 1.0.0
*/
class Widget_Audio extends Widget_Base {
/**
* Current instance.
*
* @access protected
*
* @var array
*/
protected $_current_instance = [];
/**
* Get widget name.
*
* Retrieve audio widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'audio';
}
/**
* Get widget title.
*
* Retrieve audio widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'SoundCloud', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve audio widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-headphones';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'audio', 'player', 'soundcloud', 'embed' ];
}
/**
* Register audio widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_audio',
[
'label' => __( 'SoundCloud', 'elementor' ),
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'dynamic' => [
'active' => true,
'categories' => [
TagsModule::POST_META_CATEGORY,
TagsModule::URL_CATEGORY,
],
],
'default' => [
'url' => 'https://soundcloud.com/shchxango/john-coltrane-1963-my-favorite',
],
'options' => false,
]
);
$this->add_control(
'visual',
[
'label' => __( 'Visual Player', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'no',
'options' => [
'yes' => __( 'Yes', 'elementor' ),
'no' => __( 'No', 'elementor' ),
],
]
);
$this->add_control(
'sc_options',
[
'label' => __( 'Additional Options', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'sc_auto_play',
[
'label' => __( 'Autoplay', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
]
);
$this->add_control(
'sc_buying',
[
'label' => __( 'Buy Button', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Hide', 'elementor' ),
'label_on' => __( 'Show', 'elementor' ),
'default' => 'yes',
]
);
$this->add_control(
'sc_liking',
[
'label' => __( 'Like Button', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Hide', 'elementor' ),
'label_on' => __( 'Show', 'elementor' ),
'default' => 'yes',
]
);
$this->add_control(
'sc_download',
[
'label' => __( 'Download Button', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Hide', 'elementor' ),
'label_on' => __( 'Show', 'elementor' ),
'default' => 'yes',
]
);
$this->add_control(
'sc_show_artwork',
[
'label' => __( 'Artwork', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Hide', 'elementor' ),
'label_on' => __( 'Show', 'elementor' ),
'default' => 'yes',
'condition' => [
'visual' => 'no',
],
]
);
$this->add_control(
'sc_sharing',
[
'label' => __( 'Share Button', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Hide', 'elementor' ),
'label_on' => __( 'Show', 'elementor' ),
'default' => 'yes',
]
);
$this->add_control(
'sc_show_comments',
[
'label' => __( 'Comments', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Hide', 'elementor' ),
'label_on' => __( 'Show', 'elementor' ),
'default' => 'yes',
]
);
$this->add_control(
'sc_show_playcount',
[
'label' => __( 'Play Counts', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Hide', 'elementor' ),
'label_on' => __( 'Show', 'elementor' ),
'default' => 'yes',
]
);
$this->add_control(
'sc_show_user',
[
'label' => __( 'Username', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Hide', 'elementor' ),
'label_on' => __( 'Show', 'elementor' ),
'default' => 'yes',
]
);
$this->add_control(
'sc_color',
[
'label' => __( 'Controls Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'soundcloud',
]
);
$this->end_controls_section();
}
/**
* Render audio widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
if ( empty( $settings['link'] ) ) {
return;
}
$this->_current_instance = $settings;
add_filter( 'oembed_result', [ $this, 'filter_oembed_result' ], 50, 3 );
$video_html = wp_oembed_get( $settings['link']['url'], wp_embed_defaults() );
remove_filter( 'oembed_result', [ $this, 'filter_oembed_result' ], 50 );
if ( $video_html ) : ?>
<div class="elementor-soundcloud-wrapper">
<?php echo $video_html; ?>
</div>
<?php
endif;
}
/**
* Filter audio widget oEmbed results.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access public
*
* @param string $html The HTML returned by the oEmbed provider.
*
* @return string Filtered audio widget oEmbed HTML.
*/
public function filter_oembed_result( $html ) {
$param_keys = [
'auto_play',
'buying',
'liking',
'download',
'sharing',
'show_comments',
'show_playcount',
'show_user',
'show_artwork',
];
$params = [];
foreach ( $param_keys as $param_key ) {
$params[ $param_key ] = 'yes' === $this->_current_instance[ 'sc_' . $param_key ] ? 'true' : 'false';
}
$params['color'] = str_replace( '#', '', $this->_current_instance['sc_color'] );
preg_match( '/<iframe.*src=\"(.*)\".*><\/iframe>/isU', $html, $matches );
$url = esc_url( add_query_arg( $params, $matches[1] ) );
$visual = 'yes' === $this->_current_instance['visual'] ? 'true' : 'false';
$html = str_replace( [ $matches[1], 'visual=true' ], [ $url, 'visual=' . $visual ], $html );
if ( 'false' === $visual ) {
$html = str_replace( 'height="400"', 'height="200"', $html );
}
return $html;
}
/**
* Render audio widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {}
}

View File

@@ -0,0 +1,581 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor button widget.
*
* Elementor widget that displays a button with the ability to control every
* aspect of the button design.
*
* @since 1.0.0
*/
class Widget_Button extends Widget_Base {
/**
* Get widget name.
*
* Retrieve button widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'button';
}
/**
* Get widget title.
*
* Retrieve button widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Button', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve button widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-button';
}
/**
* Get widget categories.
*
* Retrieve the list of categories the button widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* @since 2.0.0
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'basic' ];
}
/**
* Get button sizes.
*
* Retrieve an array of button sizes for the button widget.
*
* @since 1.0.0
* @access public
* @static
*
* @return array An array containing button sizes.
*/
public static function get_button_sizes() {
return [
'xs' => __( 'Extra Small', 'elementor' ),
'sm' => __( 'Small', 'elementor' ),
'md' => __( 'Medium', 'elementor' ),
'lg' => __( 'Large', 'elementor' ),
'xl' => __( 'Extra Large', 'elementor' ),
];
}
/**
* Register button widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_button',
[
'label' => __( 'Button', 'elementor' ),
]
);
$this->add_control(
'button_type',
[
'label' => __( 'Type', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => '',
'options' => [
'' => __( 'Default', 'elementor' ),
'info' => __( 'Info', 'elementor' ),
'success' => __( 'Success', 'elementor' ),
'warning' => __( 'Warning', 'elementor' ),
'danger' => __( 'Danger', 'elementor' ),
],
'prefix_class' => 'elementor-button-',
]
);
$this->add_control(
'text',
[
'label' => __( 'Text', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => __( 'Click here', 'elementor' ),
'placeholder' => __( 'Click here', 'elementor' ),
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'https://your-link.com', 'elementor' ),
'default' => [
'url' => '#',
],
]
);
$this->add_responsive_control(
'align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
],
],
'prefix_class' => 'elementor%s-align-',
'default' => '',
]
);
$this->add_control(
'size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'sm',
'options' => self::get_button_sizes(),
'style_transfer' => true,
]
);
$this->add_control(
'selected_icon',
[
'label' => __( 'Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'fa4compatibility' => 'icon',
'skin' => 'inline',
'label_block' => false,
]
);
$this->add_control(
'icon_align',
[
'label' => __( 'Icon Position', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'left',
'options' => [
'left' => __( 'Before', 'elementor' ),
'right' => __( 'After', 'elementor' ),
],
'condition' => [
'selected_icon[value]!' => '',
],
]
);
$this->add_control(
'icon_indent',
[
'label' => __( 'Icon Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 50,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-button .elementor-align-icon-right' => 'margin-left: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .elementor-button .elementor-align-icon-left' => 'margin-right: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->add_control(
'button_css_id',
[
'label' => __( 'Button ID', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => '',
'title' => __( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
'description' => __( 'Please make sure the ID is unique and not used elsewhere on the page this form is displayed. This field allows <code>A-z 0-9</code> & underscore chars without spaces.', 'elementor' ),
'separator' => 'before',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style',
[
'label' => __( 'Button', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_ACCENT,
],
'selector' => '{{WRAPPER}} .elementor-button',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'text_shadow',
'selector' => '{{WRAPPER}} .elementor-button',
]
);
$this->start_controls_tabs( 'tabs_button_style' );
$this->start_controls_tab(
'tab_button_normal',
[
'label' => __( 'Normal', 'elementor' ),
]
);
$this->add_control(
'button_text_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-button' => 'fill: {{VALUE}}; color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'background',
'label' => __( 'Background', 'elementor' ),
'types' => [ 'classic', 'gradient' ],
'exclude' => [ 'image' ],
'selector' => '{{WRAPPER}} .elementor-button',
'fields_options' => [
'background' => [
'default' => 'classic',
],
'color' => [
'global' => [
'default' => Global_Colors::COLOR_ACCENT,
],
],
],
]
);
$this->end_controls_tab();
$this->start_controls_tab(
'tab_button_hover',
[
'label' => __( 'Hover', 'elementor' ),
]
);
$this->add_control(
'hover_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-button:hover, {{WRAPPER}} .elementor-button:focus' => 'color: {{VALUE}};',
'{{WRAPPER}} .elementor-button:hover svg, {{WRAPPER}} .elementor-button:focus svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'button_background_hover',
'label' => __( 'Background', 'elementor' ),
'types' => [ 'classic', 'gradient' ],
'exclude' => [ 'image' ],
'selector' => '{{WRAPPER}} .elementor-button:hover, {{WRAPPER}} .elementor-button:focus',
'fields_options' => [
'background' => [
'default' => 'classic',
],
],
]
);
$this->add_control(
'button_hover_border_color',
[
'label' => __( 'Border Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'condition' => [
'border_border!' => '',
],
'selectors' => [
'{{WRAPPER}} .elementor-button:hover, {{WRAPPER}} .elementor-button:focus' => 'border-color: {{VALUE}};',
],
]
);
$this->add_control(
'hover_animation',
[
'label' => __( 'Hover Animation', 'elementor' ),
'type' => Controls_Manager::HOVER_ANIMATION,
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'border',
'selector' => '{{WRAPPER}} .elementor-button',
'separator' => 'before',
]
);
$this->add_control(
'border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em' ],
'selectors' => [
'{{WRAPPER}} .elementor-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'button_box_shadow',
'selector' => '{{WRAPPER}} .elementor-button',
]
);
$this->add_responsive_control(
'text_padding',
[
'label' => __( 'Padding', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'before',
]
);
$this->end_controls_section();
}
/**
* Render button widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$this->add_render_attribute( 'wrapper', 'class', 'elementor-button-wrapper' );
if ( ! empty( $settings['link']['url'] ) ) {
$this->add_link_attributes( 'button', $settings['link'] );
$this->add_render_attribute( 'button', 'class', 'elementor-button-link' );
}
$this->add_render_attribute( 'button', 'class', 'elementor-button' );
$this->add_render_attribute( 'button', 'role', 'button' );
if ( ! empty( $settings['button_css_id'] ) ) {
$this->add_render_attribute( 'button', 'id', $settings['button_css_id'] );
}
if ( ! empty( $settings['size'] ) ) {
$this->add_render_attribute( 'button', 'class', 'elementor-size-' . $settings['size'] );
}
if ( $settings['hover_animation'] ) {
$this->add_render_attribute( 'button', 'class', 'elementor-animation-' . $settings['hover_animation'] );
}
?>
<div <?php echo $this->get_render_attribute_string( 'wrapper' ); ?>>
<a <?php echo $this->get_render_attribute_string( 'button' ); ?>>
<?php $this->render_text(); ?>
</a>
</div>
<?php
}
/**
* Render button widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<#
view.addRenderAttribute( 'text', 'class', 'elementor-button-text' );
view.addInlineEditingAttributes( 'text', 'none' );
var iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, { 'aria-hidden': true }, 'i' , 'object' ),
migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' );
#>
<div class="elementor-button-wrapper">
<a id="{{ settings.button_css_id }}" class="elementor-button elementor-size-{{ settings.size }} elementor-animation-{{ settings.hover_animation }}" href="{{ settings.link.url }}" role="button">
<span class="elementor-button-content-wrapper">
<# if ( settings.icon || settings.selected_icon ) { #>
<span class="elementor-button-icon elementor-align-icon-{{ settings.icon_align }}">
<# if ( ( migrated || ! settings.icon ) && iconHTML.rendered ) { #>
{{{ iconHTML.value }}}
<# } else { #>
<i class="{{ settings.icon }}" aria-hidden="true"></i>
<# } #>
</span>
<# } #>
<span {{{ view.getRenderAttributeString( 'text' ) }}}>{{{ settings.text }}}</span>
</span>
</a>
</div>
<?php
}
/**
* Render button text.
*
* Render button widget text.
*
* @since 1.5.0
* @access protected
*/
protected function render_text() {
$settings = $this->get_settings_for_display();
$migrated = isset( $settings['__fa4_migrated']['selected_icon'] );
$is_new = empty( $settings['icon'] ) && Icons_Manager::is_migration_allowed();
if ( ! $is_new && empty( $settings['icon_align'] ) ) {
// @todo: remove when deprecated
// added as bc in 2.6
//old default
$settings['icon_align'] = $this->get_settings( 'icon_align' );
}
$this->add_render_attribute( [
'content-wrapper' => [
'class' => 'elementor-button-content-wrapper',
],
'icon-align' => [
'class' => [
'elementor-button-icon',
'elementor-align-icon-' . $settings['icon_align'],
],
],
'text' => [
'class' => 'elementor-button-text',
],
] );
$this->add_inline_editing_attributes( 'text', 'none' );
?>
<span <?php echo $this->get_render_attribute_string( 'content-wrapper' ); ?>>
<?php if ( ! empty( $settings['icon'] ) || ! empty( $settings['selected_icon']['value'] ) ) : ?>
<span <?php echo $this->get_render_attribute_string( 'icon-align' ); ?>>
<?php if ( $is_new || $migrated ) :
Icons_Manager::render_icon( $settings['selected_icon'], [ 'aria-hidden' => 'true' ] );
else : ?>
<i class="<?php echo esc_attr( $settings['icon'] ); ?>" aria-hidden="true"></i>
<?php endif; ?>
</span>
<?php endif; ?>
<span <?php echo $this->get_render_attribute_string( 'text' ); ?>><?php echo $settings['text']; ?></span>
</span>
<?php
}
public function on_import( $element ) {
return Icons_Manager::on_import_migration( $element, 'icon', 'selected_icon' );
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,374 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor counter widget.
*
* Elementor widget that displays stats and numbers in an escalating manner.
*
* @since 1.0.0
*/
class Widget_Counter extends Widget_Base {
/**
* Get widget name.
*
* Retrieve counter widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'counter';
}
/**
* Get widget title.
*
* Retrieve counter widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Counter', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve counter widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-counter';
}
/**
* Retrieve the list of scripts the counter widget depended on.
*
* Used to set scripts dependencies required to run the widget.
*
* @since 1.3.0
* @access public
*
* @return array Widget scripts dependencies.
*/
public function get_script_depends() {
return [ 'jquery-numerator' ];
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'counter' ];
}
/**
* Register counter widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_counter',
[
'label' => __( 'Counter', 'elementor' ),
]
);
$this->add_control(
'starting_number',
[
'label' => __( 'Starting Number', 'elementor' ),
'type' => Controls_Manager::NUMBER,
'default' => 0,
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'ending_number',
[
'label' => __( 'Ending Number', 'elementor' ),
'type' => Controls_Manager::NUMBER,
'default' => 100,
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'prefix',
[
'label' => __( 'Number Prefix', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => '',
'placeholder' => 1,
]
);
$this->add_control(
'suffix',
[
'label' => __( 'Number Suffix', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => '',
'placeholder' => __( 'Plus', 'elementor' ),
]
);
$this->add_control(
'duration',
[
'label' => __( 'Animation Duration', 'elementor' ),
'type' => Controls_Manager::NUMBER,
'default' => 2000,
'min' => 100,
'step' => 100,
]
);
$this->add_control(
'thousand_separator',
[
'label' => __( 'Thousand Separator', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'default' => 'yes',
'label_on' => __( 'Show', 'elementor' ),
'label_off' => __( 'Hide', 'elementor' ),
]
);
$this->add_control(
'thousand_separator_char',
[
'label' => __( 'Separator', 'elementor' ),
'type' => Controls_Manager::SELECT,
'condition' => [
'thousand_separator' => 'yes',
],
'options' => [
'' => 'Default',
'.' => 'Dot',
' ' => 'Space',
],
]
);
$this->add_control(
'title',
[
'label' => __( 'Title', 'elementor' ),
'type' => Controls_Manager::TEXT,
'label_block' => true,
'dynamic' => [
'active' => true,
],
'default' => __( 'Cool Number', 'elementor' ),
'placeholder' => __( 'Cool Number', 'elementor' ),
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_number',
[
'label' => __( 'Number', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'number_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
'selectors' => [
'{{WRAPPER}} .elementor-counter-number-wrapper' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'typography_number',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
'selector' => '{{WRAPPER}} .elementor-counter-number-wrapper',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'number_shadow',
'selector' => '{{WRAPPER}} .elementor-counter-number-wrapper',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_title',
[
'label' => __( 'Title', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_SECONDARY,
],
'selectors' => [
'{{WRAPPER}} .elementor-counter-title' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'typography_title',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_SECONDARY,
],
'selector' => '{{WRAPPER}} .elementor-counter-title',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'title_shadow',
'selector' => '{{WRAPPER}} .elementor-counter-title',
]
);
$this->end_controls_section();
}
/**
* Render counter widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<# view.addRenderAttribute( 'counter-title', {
'class': 'elementor-counter-title'
} );
view.addInlineEditingAttributes( 'counter-title' );
#>
<div class="elementor-counter">
<div class="elementor-counter-number-wrapper">
<span class="elementor-counter-number-prefix">{{{ settings.prefix }}}</span>
<span class="elementor-counter-number" data-duration="{{ settings.duration }}" data-to-value="{{ settings.ending_number }}" data-delimiter="{{ settings.thousand_separator ? settings.thousand_separator_char || ',' : '' }}">{{{ settings.starting_number }}}</span>
<span class="elementor-counter-number-suffix">{{{ settings.suffix }}}</span>
</div>
<# if ( settings.title ) {
#><div {{{ view.getRenderAttributeString( 'counter-title' ) }}}>{{{ settings.title }}}</div><#
} #>
</div>
<?php
}
/**
* Render counter widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$this->add_render_attribute( 'counter', [
'class' => 'elementor-counter-number',
'data-duration' => $settings['duration'],
'data-to-value' => $settings['ending_number'],
'data-from-value' => $settings['starting_number'],
] );
if ( ! empty( $settings['thousand_separator'] ) ) {
$delimiter = empty( $settings['thousand_separator_char'] ) ? ',' : $settings['thousand_separator_char'];
$this->add_render_attribute( 'counter', 'data-delimiter', $delimiter );
}
$this->add_render_attribute( 'counter-title', 'class', 'elementor-counter-title' );
$this->add_inline_editing_attributes( 'counter-title' );
?>
<div class="elementor-counter">
<div class="elementor-counter-number-wrapper">
<span class="elementor-counter-number-prefix"><?php echo $settings['prefix']; ?></span>
<span <?php echo $this->get_render_attribute_string( 'counter' ); ?>><?php echo $settings['starting_number']; ?></span>
<span class="elementor-counter-number-suffix"><?php echo $settings['suffix']; ?></span>
</div>
<?php if ( $settings['title'] ) : ?>
<div <?php echo $this->get_render_attribute_string( 'counter-title' ); ?>><?php echo $settings['title']; ?></div>
<?php endif; ?>
</div>
<?php
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,310 @@
<?php
namespace Elementor;
use Elementor\Modules\DynamicTags\Module as TagsModule;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor google maps widget.
*
* Elementor widget that displays an embedded google map.
*
* @since 1.0.0
*/
class Widget_Google_Maps extends Widget_Base {
/**
* Get widget name.
*
* Retrieve google maps widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'google_maps';
}
/**
* Get widget title.
*
* Retrieve google maps widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Google Maps', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve google maps widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-google-maps';
}
/**
* Get widget categories.
*
* Retrieve the list of categories the google maps widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* @since 2.0.0
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'basic' ];
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'google', 'map', 'embed', 'location' ];
}
/**
* Register google maps widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_map',
[
'label' => __( 'Map', 'elementor' ),
]
);
if ( Plugin::$instance->editor->is_edit_mode() ) {
$api_key = get_option( 'elementor_google_maps_api_key' );
if ( ! $api_key ) {
$this->add_control(
'api_key_notification',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => sprintf(
__( 'Set your Google Maps API Key in Elementor\'s <a href="%1$s" target="_blank">Integrations Settings</a> page. Create your key <a href="%2$s" target="_blank">here.', 'elementor' ),
Settings::get_url() . '#tab-integrations',
'https://developers.google.com/maps/documentation/embed/get-api-key'
),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
]
);
}
}
$default_address = __( 'London Eye, London, United Kingdom', 'elementor' );
$this->add_control(
'address',
[
'label' => __( 'Location', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
'categories' => [
TagsModule::POST_META_CATEGORY,
],
],
'placeholder' => $default_address,
'default' => $default_address,
'label_block' => true,
]
);
$this->add_control(
'zoom',
[
'label' => __( 'Zoom', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 10,
],
'range' => [
'px' => [
'min' => 1,
'max' => 20,
],
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'height',
[
'label' => __( 'Height', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 40,
'max' => 1440,
],
'vh' => [
'min' => 0,
'max' => 100,
],
],
'size_units' => [ 'px', 'vh' ],
'selectors' => [
'{{WRAPPER}} iframe' => 'height: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_map_style',
[
'label' => __( 'Map', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->start_controls_tabs( 'map_filter' );
$this->start_controls_tab( 'normal',
[
'label' => __( 'Normal', 'elementor' ),
]
);
$this->add_group_control(
Group_Control_Css_Filter::get_type(),
[
'name' => 'css_filters',
'selector' => '{{WRAPPER}} iframe',
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'hover',
[
'label' => __( 'Hover', 'elementor' ),
]
);
$this->add_group_control(
Group_Control_Css_Filter::get_type(),
[
'name' => 'css_filters_hover',
'selector' => '{{WRAPPER}}:hover iframe',
]
);
$this->add_control(
'hover_transition',
[
'label' => __( 'Transition Duration', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 3,
'step' => 0.1,
],
],
'selectors' => [
'{{WRAPPER}} iframe' => 'transition-duration: {{SIZE}}s',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
}
/**
* Render google maps widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
if ( empty( $settings['address'] ) ) {
return;
}
if ( 0 === absint( $settings['zoom']['size'] ) ) {
$settings['zoom']['size'] = 10;
}
$api_key = esc_html( get_option( 'elementor_google_maps_api_key' ) );
$params = [
rawurlencode( $settings['address'] ),
absint( $settings['zoom']['size'] ),
esc_attr( $settings['address'] ),
];
if ( $api_key ) {
$params[] = $api_key;
$url = 'https://www.google.com/maps/embed/v1/place?key=%4$s&q=%1$s&amp;zoom=%2$d';
} else {
$url = 'https://maps.google.com/maps?q=%1$s&amp;t=m&amp;z=%2$d&amp;output=embed&amp;iwloc=near';
}
?>
<div class="elementor-custom-embed">
<iframe frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="<?php echo vsprintf( $url, $params ); ?>" title="%3$s" aria-label="%3$s"></iframe>
</div>
<?php
}
/**
* Render google maps widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {}
}

View File

@@ -0,0 +1,349 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor heading widget.
*
* Elementor widget that displays an eye-catching headlines.
*
* @since 1.0.0
*/
class Widget_Heading extends Widget_Base {
/**
* Get widget name.
*
* Retrieve heading widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'heading';
}
/**
* Get widget title.
*
* Retrieve heading widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Heading', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve heading widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-t-letter';
}
/**
* Get widget categories.
*
* Retrieve the list of categories the heading widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* @since 2.0.0
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'basic' ];
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'heading', 'title', 'text' ];
}
/**
* Register heading widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_title',
[
'label' => __( 'Title', 'elementor' ),
]
);
$this->add_control(
'title',
[
'label' => __( 'Title', 'elementor' ),
'type' => Controls_Manager::TEXTAREA,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'Enter your title', 'elementor' ),
'default' => __( 'Add Your Heading Text Here', 'elementor' ),
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'dynamic' => [
'active' => true,
],
'default' => [
'url' => '',
],
'separator' => 'before',
]
);
$this->add_control(
'size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'default',
'options' => [
'default' => __( 'Default', 'elementor' ),
'small' => __( 'Small', 'elementor' ),
'medium' => __( 'Medium', 'elementor' ),
'large' => __( 'Large', 'elementor' ),
'xl' => __( 'XL', 'elementor' ),
'xxl' => __( 'XXL', 'elementor' ),
],
]
);
$this->add_control(
'header_size',
[
'label' => __( 'HTML Tag', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'h1' => 'H1',
'h2' => 'H2',
'h3' => 'H3',
'h4' => 'H4',
'h5' => 'H5',
'h6' => 'H6',
'div' => 'div',
'span' => 'span',
'p' => 'p',
],
'default' => 'h2',
]
);
$this->add_responsive_control(
'align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
],
],
'default' => '',
'selectors' => [
'{{WRAPPER}}' => 'text-align: {{VALUE}};',
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_title_style',
[
'label' => __( 'Title', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
'selectors' => [
'{{WRAPPER}} .elementor-heading-title' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
'selector' => '{{WRAPPER}} .elementor-heading-title',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'text_shadow',
'selector' => '{{WRAPPER}} .elementor-heading-title',
]
);
$this->add_control(
'blend_mode',
[
'label' => __( 'Blend Mode', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'' => __( 'Normal', 'elementor' ),
'multiply' => 'Multiply',
'screen' => 'Screen',
'overlay' => 'Overlay',
'darken' => 'Darken',
'lighten' => 'Lighten',
'color-dodge' => 'Color Dodge',
'saturation' => 'Saturation',
'color' => 'Color',
'difference' => 'Difference',
'exclusion' => 'Exclusion',
'hue' => 'Hue',
'luminosity' => 'Luminosity',
],
'selectors' => [
'{{WRAPPER}} .elementor-heading-title' => 'mix-blend-mode: {{VALUE}}',
],
'separator' => 'none',
]
);
$this->end_controls_section();
}
/**
* Render heading widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
if ( '' === $settings['title'] ) {
return;
}
$this->add_render_attribute( 'title', 'class', 'elementor-heading-title' );
if ( ! empty( $settings['size'] ) ) {
$this->add_render_attribute( 'title', 'class', 'elementor-size-' . $settings['size'] );
}
$this->add_inline_editing_attributes( 'title' );
$title = $settings['title'];
if ( ! empty( $settings['link']['url'] ) ) {
$this->add_link_attributes( 'url', $settings['link'] );
$title = sprintf( '<a %1$s>%2$s</a>', $this->get_render_attribute_string( 'url' ), $title );
}
$title_html = sprintf( '<%1$s %2$s>%3$s</%1$s>', Utils::validate_html_tag( $settings['header_size'] ), $this->get_render_attribute_string( 'title' ), $title );
echo $title_html;
}
/**
* Render heading widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<#
var title = settings.title;
if ( '' !== settings.link.url ) {
title = '<a href="' + settings.link.url + '">' + title + '</a>';
}
view.addRenderAttribute( 'title', 'class', [ 'elementor-heading-title', 'elementor-size-' + settings.size ] );
view.addInlineEditingAttributes( 'title' );
var headerSizeTag = elementor.helpers.validateHTMLTag( settings.header_size ),
title_html = '<' + headerSizeTag + ' ' + view.getRenderAttributeString( 'title' ) + '>' + title + '</' + headerSizeTag + '>';
print( title_html );
#>
<?php
}
}

View File

@@ -0,0 +1,128 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor HTML widget.
*
* Elementor widget that insert a custom HTML code into the page.
*
* @since 1.0.0
*/
class Widget_Html extends Widget_Base {
/**
* Get widget name.
*
* Retrieve HTML widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'html';
}
/**
* Get widget title.
*
* Retrieve HTML widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'HTML', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve HTML widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-code';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'html', 'code' ];
}
/**
* Register HTML widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_title',
[
'label' => __( 'HTML Code', 'elementor' ),
]
);
$this->add_control(
'html',
[
'label' => '',
'type' => Controls_Manager::CODE,
'default' => '',
'placeholder' => __( 'Enter your code', 'elementor' ),
'show_label' => false,
]
);
$this->end_controls_section();
}
/**
* Render HTML widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
echo $this->get_settings_for_display( 'html' );
}
/**
* Render HTML widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
{{{ settings.html }}}
<?php
}
}

View File

@@ -0,0 +1,733 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor icon box widget.
*
* Elementor widget that displays an icon, a headline and a text.
*
* @since 1.0.0
*/
class Widget_Icon_Box extends Widget_Base {
/**
* Get widget name.
*
* Retrieve icon box widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'icon-box';
}
/**
* Get widget title.
*
* Retrieve icon box widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Icon Box', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve icon box widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-icon-box';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'icon box', 'icon' ];
}
/**
* Register icon box widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_icon',
[
'label' => __( 'Icon Box', 'elementor' ),
]
);
$this->add_control(
'selected_icon',
[
'label' => __( 'Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'fa4compatibility' => 'icon',
'default' => [
'value' => 'fas fa-star',
'library' => 'fa-solid',
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'default' => __( 'Default', 'elementor' ),
'stacked' => __( 'Stacked', 'elementor' ),
'framed' => __( 'Framed', 'elementor' ),
],
'default' => 'default',
'prefix_class' => 'elementor-view-',
]
);
$this->add_control(
'shape',
[
'label' => __( 'Shape', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'circle' => __( 'Circle', 'elementor' ),
'square' => __( 'Square', 'elementor' ),
],
'default' => 'circle',
'condition' => [
'view!' => 'default',
'selected_icon[value]!' => '',
],
'prefix_class' => 'elementor-shape-',
]
);
$this->add_control(
'title_text',
[
'label' => __( 'Title & Description', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => __( 'This is the heading', 'elementor' ),
'placeholder' => __( 'Enter your title', 'elementor' ),
'label_block' => true,
]
);
$this->add_control(
'description_text',
[
'label' => '',
'type' => Controls_Manager::TEXTAREA,
'dynamic' => [
'active' => true,
],
'default' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
'placeholder' => __( 'Enter your description', 'elementor' ),
'rows' => 10,
'separator' => 'none',
'show_label' => false,
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'https://your-link.com', 'elementor' ),
'separator' => 'before',
]
);
$this->add_control(
'position',
[
'label' => __( 'Icon Position', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'default' => 'top',
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-h-align-left',
],
'top' => [
'title' => __( 'Top', 'elementor' ),
'icon' => 'eicon-v-align-top',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-h-align-right',
],
],
'prefix_class' => 'elementor-position-',
'toggle' => false,
'conditions' => [
'relation' => 'or',
'terms' => [
[
'name' => 'selected_icon[value]',
'operator' => '!=',
'value' => '',
],
],
],
]
);
$this->add_control(
'title_size',
[
'label' => __( 'Title HTML Tag', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'h1' => 'H1',
'h2' => 'H2',
'h3' => 'H3',
'h4' => 'H4',
'h5' => 'H5',
'h6' => 'H6',
'div' => 'div',
'span' => 'span',
'p' => 'p',
],
'default' => 'h3',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_icon',
[
'label' => __( 'Icon', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'conditions' => [
'relation' => 'or',
'terms' => [
[
'name' => 'selected_icon[value]',
'operator' => '!=',
'value' => '',
],
],
],
]
);
$this->start_controls_tabs( 'icon_colors' );
$this->start_controls_tab(
'icon_colors_normal',
[
'label' => __( 'Normal', 'elementor' ),
]
);
$this->add_control(
'primary_color',
[
'label' => __( 'Primary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
'default' => '',
'selectors' => [
'{{WRAPPER}}.elementor-view-stacked .elementor-icon' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-framed .elementor-icon, {{WRAPPER}}.elementor-view-default .elementor-icon' => 'fill: {{VALUE}}; color: {{VALUE}}; border-color: {{VALUE}};',
],
]
);
$this->add_control(
'secondary_color',
[
'label' => __( 'Secondary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'condition' => [
'view!' => 'default',
],
'selectors' => [
'{{WRAPPER}}.elementor-view-framed .elementor-icon' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-stacked .elementor-icon' => 'fill: {{VALUE}}; color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab(
'icon_colors_hover',
[
'label' => __( 'Hover', 'elementor' ),
]
);
$this->add_control(
'hover_primary_color',
[
'label' => __( 'Primary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}}.elementor-view-stacked .elementor-icon:hover' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-framed .elementor-icon:hover, {{WRAPPER}}.elementor-view-default .elementor-icon:hover' => 'fill: {{VALUE}}; color: {{VALUE}}; border-color: {{VALUE}};',
],
]
);
$this->add_control(
'hover_secondary_color',
[
'label' => __( 'Secondary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'condition' => [
'view!' => 'default',
],
'selectors' => [
'{{WRAPPER}}.elementor-view-framed .elementor-icon:hover' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-stacked .elementor-icon:hover' => 'fill: {{VALUE}}; color: {{VALUE}};',
],
]
);
$this->add_control(
'hover_animation',
[
'label' => __( 'Hover Animation', 'elementor' ),
'type' => Controls_Manager::HOVER_ANIMATION,
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_responsive_control(
'icon_space',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 15,
],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}.elementor-position-right .elementor-icon-box-icon' => 'margin-left: {{SIZE}}{{UNIT}};',
'{{WRAPPER}}.elementor-position-left .elementor-icon-box-icon' => 'margin-right: {{SIZE}}{{UNIT}};',
'{{WRAPPER}}.elementor-position-top .elementor-icon-box-icon' => 'margin-bottom: {{SIZE}}{{UNIT}};',
'(mobile){{WRAPPER}} .elementor-icon-box-icon' => 'margin-bottom: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'icon_size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 6,
'max' => 300,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-icon' => 'font-size: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'icon_padding',
[
'label' => __( 'Padding', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'selectors' => [
'{{WRAPPER}} .elementor-icon' => 'padding: {{SIZE}}{{UNIT}};',
],
'range' => [
'em' => [
'min' => 0,
'max' => 5,
],
],
'condition' => [
'view!' => 'default',
],
]
);
$this->add_control(
'rotate',
[
'label' => __( 'Rotate', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 0,
'unit' => 'deg',
],
'selectors' => [
'{{WRAPPER}} .elementor-icon i' => 'transform: rotate({{SIZE}}{{UNIT}});',
],
]
);
$this->add_control(
'border_width',
[
'label' => __( 'Border Width', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'selectors' => [
'{{WRAPPER}} .elementor-icon' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'view' => 'framed',
],
]
);
$this->add_control(
'border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'view!' => 'default',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_content',
[
'label' => __( 'Content', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'text_align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
],
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-box-wrapper' => 'text-align: {{VALUE}};',
],
]
);
$this->add_control(
'content_vertical_alignment',
[
'label' => __( 'Vertical Alignment', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'top' => __( 'Top', 'elementor' ),
'middle' => __( 'Middle', 'elementor' ),
'bottom' => __( 'Bottom', 'elementor' ),
],
'default' => 'top',
'prefix_class' => 'elementor-vertical-align-',
]
);
$this->add_control(
'heading_title',
[
'label' => __( 'Title', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_responsive_control(
'title_bottom_space',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-box-title' => 'margin-bottom: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-icon-box-title' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'selector' => '{{WRAPPER}} .elementor-icon-box-title, {{WRAPPER}} .elementor-icon-box-title a',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'title_shadow',
'selector' => '{{WRAPPER}} .elementor-icon-box-title',
]
);
$this->add_control(
'heading_description',
[
'label' => __( 'Description', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'description_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-icon-box-description' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'description_typography',
'selector' => '{{WRAPPER}} .elementor-icon-box-description',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'description_shadow',
'selector' => '{{WRAPPER}} .elementor-icon-box-description',
]
);
$this->end_controls_section();
}
/**
* Render icon box widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$this->add_render_attribute( 'icon', 'class', [ 'elementor-icon', 'elementor-animation-' . $settings['hover_animation'] ] );
$icon_tag = 'span';
if ( ! isset( $settings['icon'] ) && ! Icons_Manager::is_migration_allowed() ) {
// add old default
$settings['icon'] = 'fa fa-star';
}
$has_icon = ! empty( $settings['icon'] );
if ( ! empty( $settings['link']['url'] ) ) {
$icon_tag = 'a';
$this->add_link_attributes( 'link', $settings['link'] );
}
if ( $has_icon ) {
$this->add_render_attribute( 'i', 'class', $settings['icon'] );
$this->add_render_attribute( 'i', 'aria-hidden', 'true' );
}
$icon_attributes = $this->get_render_attribute_string( 'icon' );
$link_attributes = $this->get_render_attribute_string( 'link' );
$this->add_render_attribute( 'description_text', 'class', 'elementor-icon-box-description' );
$this->add_inline_editing_attributes( 'title_text', 'none' );
$this->add_inline_editing_attributes( 'description_text' );
if ( ! $has_icon && ! empty( $settings['selected_icon']['value'] ) ) {
$has_icon = true;
}
$migrated = isset( $settings['__fa4_migrated']['selected_icon'] );
$is_new = ! isset( $settings['icon'] ) && Icons_Manager::is_migration_allowed();
?>
<div class="elementor-icon-box-wrapper">
<?php if ( $has_icon ) : ?>
<div class="elementor-icon-box-icon">
<<?php echo implode( ' ', [ $icon_tag, $icon_attributes, $link_attributes ] ); ?>>
<?php
if ( $is_new || $migrated ) {
Icons_Manager::render_icon( $settings['selected_icon'], [ 'aria-hidden' => 'true' ] );
} elseif ( ! empty( $settings['icon'] ) ) {
?><i <?php echo $this->get_render_attribute_string( 'i' ); ?>></i><?php
}
?>
</<?php echo $icon_tag; ?>>
</div>
<?php endif; ?>
<div class="elementor-icon-box-content">
<<?php echo Utils::validate_html_tag( $settings['title_size'] ); ?> class="elementor-icon-box-title">
<<?php echo implode( ' ', [ $icon_tag, $link_attributes ] ); ?><?php echo $this->get_render_attribute_string( 'title_text' ); ?>><?php echo $settings['title_text']; ?></<?php echo $icon_tag; ?>>
</<?php echo Utils::validate_html_tag( $settings['title_size'] ); ?>>
<?php if ( ! Utils::is_empty( $settings['description_text'] ) ) : ?>
<p <?php echo $this->get_render_attribute_string( 'description_text' ); ?>><?php echo $settings['description_text']; ?></p>
<?php endif; ?>
</div>
</div>
<?php
}
/**
* Render icon box widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<#
var link = settings.link.url ? 'href="' + settings.link.url + '"' : '',
iconTag = link ? 'a' : 'span',
iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, { 'aria-hidden': true }, 'i' , 'object' ),
migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' );
view.addRenderAttribute( 'description_text', 'class', 'elementor-icon-box-description' );
view.addInlineEditingAttributes( 'title_text', 'none' );
view.addInlineEditingAttributes( 'description_text' );
#>
<div class="elementor-icon-box-wrapper">
<?php // settings.icon is needed for older version ?>
<# if ( settings.icon || settings.selected_icon.value ) { #>
<div class="elementor-icon-box-icon">
<{{{ iconTag + ' ' + link }}} class="elementor-icon elementor-animation-{{ settings.hover_animation }}">
<# if ( iconHTML && iconHTML.rendered && ( ! settings.icon || migrated ) ) { #>
{{{ iconHTML.value }}}
<# } else { #>
<i class="{{ settings.icon }}" aria-hidden="true"></i>
<# } #>
</{{{ iconTag }}}>
</div>
<# } #>
<div class="elementor-icon-box-content">
<# var titleSizeTag = elementor.helpers.validateHTMLTag( settings.title_size ); #>
<{{{ titleSizeTag }}} class="elementor-icon-box-title">
<{{{ iconTag + ' ' + link }}} {{{ view.getRenderAttributeString( 'title_text' ) }}}>{{{ settings.title_text }}}</{{{ iconTag }}}>
</{{{ titleSizeTag }}}>
<# if ( settings.description_text ) { #>
<p {{{ view.getRenderAttributeString( 'description_text' ) }}}>{{{ settings.description_text }}}</p>
<# } #>
</div>
</div>
<?php
}
public function on_import( $element ) {
return Icons_Manager::on_import_migration( $element, 'icon', 'selected_icon', true );
}
}

View File

@@ -0,0 +1,681 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor icon list widget.
*
* Elementor widget that displays a bullet list with any chosen icons and texts.
*
* @since 1.0.0
*/
class Widget_Icon_List extends Widget_Base {
/**
* Get widget name.
*
* Retrieve icon list widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'icon-list';
}
/**
* Get widget title.
*
* Retrieve icon list widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Icon List', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve icon list widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-bullet-list';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'icon list', 'icon', 'list' ];
}
/**
* Register icon list widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_icon',
[
'label' => __( 'Icon List', 'elementor' ),
]
);
$this->add_control(
'view',
[
'label' => __( 'Layout', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'default' => 'traditional',
'options' => [
'traditional' => [
'title' => __( 'Default', 'elementor' ),
'icon' => 'eicon-editor-list-ul',
],
'inline' => [
'title' => __( 'Inline', 'elementor' ),
'icon' => 'eicon-ellipsis-h',
],
],
'render_type' => 'template',
'classes' => 'elementor-control-start-end',
'style_transfer' => true,
'prefix_class' => 'elementor-icon-list--layout-',
]
);
$repeater = new Repeater();
$repeater->add_control(
'text',
[
'label' => __( 'Text', 'elementor' ),
'type' => Controls_Manager::TEXT,
'label_block' => true,
'placeholder' => __( 'List Item', 'elementor' ),
'default' => __( 'List Item', 'elementor' ),
'dynamic' => [
'active' => true,
],
]
);
$repeater->add_control(
'selected_icon',
[
'label' => __( 'Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'default' => [
'value' => 'fas fa-check',
'library' => 'fa-solid',
],
'fa4compatibility' => 'icon',
]
);
$repeater->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'https://your-link.com', 'elementor' ),
]
);
$this->add_control(
'icon_list',
[
'label' => __( 'Items', 'elementor' ),
'type' => Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'default' => [
[
'text' => __( 'List Item #1', 'elementor' ),
'selected_icon' => [
'value' => 'fas fa-check',
'library' => 'fa-solid',
],
],
[
'text' => __( 'List Item #2', 'elementor' ),
'selected_icon' => [
'value' => 'fas fa-times',
'library' => 'fa-solid',
],
],
[
'text' => __( 'List Item #3', 'elementor' ),
'selected_icon' => [
'value' => 'fas fa-dot-circle',
'library' => 'fa-solid',
],
],
],
'title_field' => '{{{ elementor.helpers.renderIcon( this, selected_icon, {}, "i", "panel" ) || \'<i class="{{ icon }}" aria-hidden="true"></i>\' }}} {{{ text }}}',
]
);
$this->add_control(
'link_click',
[
'label' => __( 'Apply Link On', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'full_width' => __( 'Full Width', 'elementor' ),
'inline' => __( 'Inline', 'elementor' ),
],
'default' => 'full_width',
'separator' => 'before',
'prefix_class' => 'elementor-list-item-link-',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_icon_list',
[
'label' => __( 'List', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'space_between',
[
'label' => __( 'Space Between', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 50,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-items:not(.elementor-inline-items) .elementor-icon-list-item:not(:last-child)' => 'padding-bottom: calc({{SIZE}}{{UNIT}}/2)',
'{{WRAPPER}} .elementor-icon-list-items:not(.elementor-inline-items) .elementor-icon-list-item:not(:first-child)' => 'margin-top: calc({{SIZE}}{{UNIT}}/2)',
'{{WRAPPER}} .elementor-icon-list-items.elementor-inline-items .elementor-icon-list-item' => 'margin-right: calc({{SIZE}}{{UNIT}}/2); margin-left: calc({{SIZE}}{{UNIT}}/2)',
'{{WRAPPER}} .elementor-icon-list-items.elementor-inline-items' => 'margin-right: calc(-{{SIZE}}{{UNIT}}/2); margin-left: calc(-{{SIZE}}{{UNIT}}/2)',
'body.rtl {{WRAPPER}} .elementor-icon-list-items.elementor-inline-items .elementor-icon-list-item:after' => 'left: calc(-{{SIZE}}{{UNIT}}/2)',
'body:not(.rtl) {{WRAPPER}} .elementor-icon-list-items.elementor-inline-items .elementor-icon-list-item:after' => 'right: calc(-{{SIZE}}{{UNIT}}/2)',
],
]
);
$this->add_responsive_control(
'icon_align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-h-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-h-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-h-align-right',
],
],
'prefix_class' => 'elementor%s-align-',
]
);
$this->add_control(
'divider',
[
'label' => __( 'Divider', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Off', 'elementor' ),
'label_on' => __( 'On', 'elementor' ),
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-item:not(:last-child):after' => 'content: ""',
],
'separator' => 'before',
]
);
$this->add_control(
'divider_style',
[
'label' => __( 'Style', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'solid' => __( 'Solid', 'elementor' ),
'double' => __( 'Double', 'elementor' ),
'dotted' => __( 'Dotted', 'elementor' ),
'dashed' => __( 'Dashed', 'elementor' ),
],
'default' => 'solid',
'condition' => [
'divider' => 'yes',
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-items:not(.elementor-inline-items) .elementor-icon-list-item:not(:last-child):after' => 'border-top-style: {{VALUE}}',
'{{WRAPPER}} .elementor-icon-list-items.elementor-inline-items .elementor-icon-list-item:not(:last-child):after' => 'border-left-style: {{VALUE}}',
],
]
);
$this->add_control(
'divider_weight',
[
'label' => __( 'Weight', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 1,
],
'range' => [
'px' => [
'min' => 1,
'max' => 20,
],
],
'condition' => [
'divider' => 'yes',
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-items:not(.elementor-inline-items) .elementor-icon-list-item:not(:last-child):after' => 'border-top-width: {{SIZE}}{{UNIT}}',
'{{WRAPPER}} .elementor-inline-items .elementor-icon-list-item:not(:last-child):after' => 'border-left-width: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'divider_width',
[
'label' => __( 'Width', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'unit' => '%',
],
'condition' => [
'divider' => 'yes',
'view!' => 'inline',
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-item:not(:last-child):after' => 'width: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'divider_height',
[
'label' => __( 'Height', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ '%', 'px' ],
'default' => [
'unit' => '%',
],
'range' => [
'px' => [
'min' => 1,
'max' => 100,
],
'%' => [
'min' => 1,
'max' => 100,
],
],
'condition' => [
'divider' => 'yes',
'view' => 'inline',
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-item:not(:last-child):after' => 'height: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'divider_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '#ddd',
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
'condition' => [
'divider' => 'yes',
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-item:not(:last-child):after' => 'border-color: {{VALUE}}',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_icon_style',
[
'label' => __( 'Icon', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'icon_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-icon i' => 'color: {{VALUE}};',
'{{WRAPPER}} .elementor-icon-list-icon svg' => 'fill: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
]
);
$this->add_control(
'icon_color_hover',
[
'label' => __( 'Hover', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-item:hover .elementor-icon-list-icon i' => 'color: {{VALUE}};',
'{{WRAPPER}} .elementor-icon-list-item:hover .elementor-icon-list-icon svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'icon_size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 14,
],
'range' => [
'px' => [
'min' => 6,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-icon i' => 'font-size: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .elementor-icon-list-icon svg' => 'width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'icon_self_align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-h-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-h-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-h-align-right',
],
],
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-icon' => 'text-align: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_text_style',
[
'label' => __( 'Text', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'text_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-text' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_SECONDARY,
],
]
);
$this->add_control(
'text_color_hover',
[
'label' => __( 'Hover', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-item:hover .elementor-icon-list-text' => 'color: {{VALUE}};',
],
]
);
$this->add_control(
'text_indent',
[
'label' => __( 'Text Indent', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 50,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-icon-list-text' => is_rtl() ? 'padding-right: {{SIZE}}{{UNIT}};' : 'padding-left: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'icon_typography',
'selector' => '{{WRAPPER}} .elementor-icon-list-item, {{WRAPPER}} .elementor-icon-list-item a',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'text_shadow',
'selector' => '{{WRAPPER}} .elementor-icon-list-text',
]
);
$this->end_controls_section();
}
/**
* Render icon list widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$fallback_defaults = [
'fa fa-check',
'fa fa-times',
'fa fa-dot-circle-o',
];
$this->add_render_attribute( 'icon_list', 'class', 'elementor-icon-list-items' );
$this->add_render_attribute( 'list_item', 'class', 'elementor-icon-list-item' );
if ( 'inline' === $settings['view'] ) {
$this->add_render_attribute( 'icon_list', 'class', 'elementor-inline-items' );
$this->add_render_attribute( 'list_item', 'class', 'elementor-inline-item' );
}
?>
<ul <?php echo $this->get_render_attribute_string( 'icon_list' ); ?>>
<?php
foreach ( $settings['icon_list'] as $index => $item ) :
$repeater_setting_key = $this->get_repeater_setting_key( 'text', 'icon_list', $index );
$this->add_render_attribute( $repeater_setting_key, 'class', 'elementor-icon-list-text' );
$this->add_inline_editing_attributes( $repeater_setting_key );
$migration_allowed = Icons_Manager::is_migration_allowed();
?>
<li <?php echo $this->get_render_attribute_string( 'list_item' ); ?>>
<?php
if ( ! empty( $item['link']['url'] ) ) {
$link_key = 'link_' . $index;
$this->add_link_attributes( $link_key, $item['link'] );
echo '<a ' . $this->get_render_attribute_string( $link_key ) . '>';
}
// add old default
if ( ! isset( $item['icon'] ) && ! $migration_allowed ) {
$item['icon'] = isset( $fallback_defaults[ $index ] ) ? $fallback_defaults[ $index ] : 'fa fa-check';
}
$migrated = isset( $item['__fa4_migrated']['selected_icon'] );
$is_new = ! isset( $item['icon'] ) && $migration_allowed;
if ( ! empty( $item['icon'] ) || ( ! empty( $item['selected_icon']['value'] ) && $is_new ) ) :
?>
<span class="elementor-icon-list-icon">
<?php
if ( $is_new || $migrated ) {
Icons_Manager::render_icon( $item['selected_icon'], [ 'aria-hidden' => 'true' ] );
} else { ?>
<i class="<?php echo esc_attr( $item['icon'] ); ?>" aria-hidden="true"></i>
<?php } ?>
</span>
<?php endif; ?>
<span <?php echo $this->get_render_attribute_string( $repeater_setting_key ); ?>><?php echo $item['text']; ?></span>
<?php if ( ! empty( $item['link']['url'] ) ) : ?>
</a>
<?php endif; ?>
</li>
<?php
endforeach;
?>
</ul>
<?php
}
/**
* Render icon list widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<#
view.addRenderAttribute( 'icon_list', 'class', 'elementor-icon-list-items' );
view.addRenderAttribute( 'list_item', 'class', 'elementor-icon-list-item' );
if ( 'inline' == settings.view ) {
view.addRenderAttribute( 'icon_list', 'class', 'elementor-inline-items' );
view.addRenderAttribute( 'list_item', 'class', 'elementor-inline-item' );
}
var iconsHTML = {},
migrated = {};
#>
<# if ( settings.icon_list ) { #>
<ul {{{ view.getRenderAttributeString( 'icon_list' ) }}}>
<# _.each( settings.icon_list, function( item, index ) {
var iconTextKey = view.getRepeaterSettingKey( 'text', 'icon_list', index );
view.addRenderAttribute( iconTextKey, 'class', 'elementor-icon-list-text' );
view.addInlineEditingAttributes( iconTextKey ); #>
<li {{{ view.getRenderAttributeString( 'list_item' ) }}}>
<# if ( item.link && item.link.url ) { #>
<a href="{{ item.link.url }}">
<# } #>
<# if ( item.icon || item.selected_icon.value ) { #>
<span class="elementor-icon-list-icon">
<#
iconsHTML[ index ] = elementor.helpers.renderIcon( view, item.selected_icon, { 'aria-hidden': true }, 'i', 'object' );
migrated[ index ] = elementor.helpers.isIconMigrated( item, 'selected_icon' );
if ( iconsHTML[ index ] && iconsHTML[ index ].rendered && ( ! item.icon || migrated[ index ] ) ) { #>
{{{ iconsHTML[ index ].value }}}
<# } else { #>
<i class="{{ item.icon }}" aria-hidden="true"></i>
<# }
#>
</span>
<# } #>
<span {{{ view.getRenderAttributeString( iconTextKey ) }}}>{{{ item.text }}}</span>
<# if ( item.link && item.link.url ) { #>
</a>
<# } #>
</li>
<#
} ); #>
</ul>
<# } #>
<?php
}
public function on_import( $element ) {
return Icons_Manager::on_import_migration( $element, 'icon', 'selected_icon', true );
}
}

View File

@@ -0,0 +1,466 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
/**
* Elementor icon widget.
*
* Elementor widget that displays an icon from over 600+ icons.
*
* @since 1.0.0
*/
class Widget_Icon extends Widget_Base {
/**
* Get widget name.
*
* Retrieve icon widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'icon';
}
/**
* Get widget title.
*
* Retrieve icon widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Icon', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve icon widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-favorite';
}
/**
* Get widget categories.
*
* Retrieve the list of categories the icon widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* @since 2.0.0
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'basic' ];
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'icon' ];
}
/**
* Register icon widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_icon',
[
'label' => __( 'Icon', 'elementor' ),
]
);
$this->add_control(
'selected_icon',
[
'label' => __( 'Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'fa4compatibility' => 'icon',
'default' => [
'value' => 'fas fa-star',
'library' => 'fa-solid',
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'default' => __( 'Default', 'elementor' ),
'stacked' => __( 'Stacked', 'elementor' ),
'framed' => __( 'Framed', 'elementor' ),
],
'default' => 'default',
'prefix_class' => 'elementor-view-',
]
);
$this->add_control(
'shape',
[
'label' => __( 'Shape', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'circle' => __( 'Circle', 'elementor' ),
'square' => __( 'Square', 'elementor' ),
],
'default' => 'circle',
'condition' => [
'view!' => 'default',
],
'prefix_class' => 'elementor-shape-',
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'https://your-link.com', 'elementor' ),
]
);
$this->add_responsive_control(
'align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
],
'default' => 'center',
'selectors' => [
'{{WRAPPER}} .elementor-icon-wrapper' => 'text-align: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_icon',
[
'label' => __( 'Icon', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->start_controls_tabs( 'icon_colors' );
$this->start_controls_tab(
'icon_colors_normal',
[
'label' => __( 'Normal', 'elementor' ),
]
);
$this->add_control(
'primary_color',
[
'label' => __( 'Primary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}}.elementor-view-stacked .elementor-icon' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-framed .elementor-icon, {{WRAPPER}}.elementor-view-default .elementor-icon' => 'color: {{VALUE}}; border-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-framed .elementor-icon, {{WRAPPER}}.elementor-view-default .elementor-icon svg' => 'fill: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
]
);
$this->add_control(
'secondary_color',
[
'label' => __( 'Secondary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'condition' => [
'view!' => 'default',
],
'selectors' => [
'{{WRAPPER}}.elementor-view-framed .elementor-icon' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-stacked .elementor-icon' => 'color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-stacked .elementor-icon svg' => 'fill: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab(
'icon_colors_hover',
[
'label' => __( 'Hover', 'elementor' ),
]
);
$this->add_control(
'hover_primary_color',
[
'label' => __( 'Primary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}}.elementor-view-stacked .elementor-icon:hover' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-framed .elementor-icon:hover, {{WRAPPER}}.elementor-view-default .elementor-icon:hover' => 'color: {{VALUE}}; border-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-framed .elementor-icon:hover, {{WRAPPER}}.elementor-view-default .elementor-icon:hover svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_control(
'hover_secondary_color',
[
'label' => __( 'Secondary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'condition' => [
'view!' => 'default',
],
'selectors' => [
'{{WRAPPER}}.elementor-view-framed .elementor-icon:hover' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-stacked .elementor-icon:hover' => 'color: {{VALUE}};',
'{{WRAPPER}}.elementor-view-stacked .elementor-icon:hover svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_control(
'hover_animation',
[
'label' => __( 'Hover Animation', 'elementor' ),
'type' => Controls_Manager::HOVER_ANIMATION,
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_responsive_control(
'size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 6,
'max' => 300,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-icon' => 'font-size: {{SIZE}}{{UNIT}};',
],
'separator' => 'before',
]
);
$this->add_control(
'icon_padding',
[
'label' => __( 'Padding', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'selectors' => [
'{{WRAPPER}} .elementor-icon' => 'padding: {{SIZE}}{{UNIT}};',
],
'range' => [
'em' => [
'min' => 0,
'max' => 5,
],
],
'condition' => [
'view!' => 'default',
],
]
);
$this->add_responsive_control(
'rotate',
[
'label' => __( 'Rotate', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'deg' ],
'default' => [
'size' => 0,
'unit' => 'deg',
],
'tablet_default' => [
'unit' => 'deg',
],
'mobile_default' => [
'unit' => 'deg',
],
'selectors' => [
'{{WRAPPER}} .elementor-icon i, {{WRAPPER}} .elementor-icon svg' => 'transform: rotate({{SIZE}}{{UNIT}});',
],
]
);
$this->add_control(
'border_width',
[
'label' => __( 'Border Width', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'selectors' => [
'{{WRAPPER}} .elementor-icon' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'view' => 'framed',
],
]
);
$this->add_control(
'border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'view!' => 'default',
],
]
);
$this->end_controls_section();
}
/**
* Render icon widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$this->add_render_attribute( 'wrapper', 'class', 'elementor-icon-wrapper' );
$this->add_render_attribute( 'icon-wrapper', 'class', 'elementor-icon' );
if ( ! empty( $settings['hover_animation'] ) ) {
$this->add_render_attribute( 'icon-wrapper', 'class', 'elementor-animation-' . $settings['hover_animation'] );
}
$icon_tag = 'div';
if ( ! empty( $settings['link']['url'] ) ) {
$this->add_link_attributes( 'icon-wrapper', $settings['link'] );
$icon_tag = 'a';
}
if ( empty( $settings['icon'] ) && ! Icons_Manager::is_migration_allowed() ) {
// add old default
$settings['icon'] = 'fa fa-star';
}
if ( ! empty( $settings['icon'] ) ) {
$this->add_render_attribute( 'icon', 'class', $settings['icon'] );
$this->add_render_attribute( 'icon', 'aria-hidden', 'true' );
}
$migrated = isset( $settings['__fa4_migrated']['selected_icon'] );
$is_new = empty( $settings['icon'] ) && Icons_Manager::is_migration_allowed();
?>
<div <?php echo $this->get_render_attribute_string( 'wrapper' ); ?>>
<<?php echo $icon_tag . ' ' . $this->get_render_attribute_string( 'icon-wrapper' ); ?>>
<?php if ( $is_new || $migrated ) :
Icons_Manager::render_icon( $settings['selected_icon'], [ 'aria-hidden' => 'true' ] );
else : ?>
<i <?php echo $this->get_render_attribute_string( 'icon' ); ?>></i>
<?php endif; ?>
</<?php echo $icon_tag; ?>>
</div>
<?php
}
/**
* Render icon widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<# var link = settings.link.url ? 'href="' + settings.link.url + '"' : '',
iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, { 'aria-hidden': true }, 'i' , 'object' ),
migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' ),
iconTag = link ? 'a' : 'div';
#>
<div class="elementor-icon-wrapper">
<{{{ iconTag }}} class="elementor-icon elementor-animation-{{ settings.hover_animation }}" {{{ link }}}>
<# if ( iconHTML && iconHTML.rendered && ( ! settings.icon || migrated ) ) { #>
{{{ iconHTML.value }}}
<# } else { #>
<i class="{{ settings.icon }}" aria-hidden="true"></i>
<# } #>
</{{{ iconTag }}}>
</div>
<?php
}
}

View File

@@ -0,0 +1,685 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor image box widget.
*
* Elementor widget that displays an image, a headline and a text.
*
* @since 1.0.0
*/
class Widget_Image_Box extends Widget_Base {
/**
* Get widget name.
*
* Retrieve image box widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'image-box';
}
/**
* Get widget title.
*
* Retrieve image box widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Image Box', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve image box widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-image-box';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'image', 'photo', 'visual', 'box' ];
}
/**
* Register image box widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_image',
[
'label' => __( 'Image Box', 'elementor' ),
]
);
$this->add_control(
'image',
[
'label' => __( 'Choose Image', 'elementor' ),
'type' => Controls_Manager::MEDIA,
'dynamic' => [
'active' => true,
],
'default' => [
'url' => Utils::get_placeholder_image_src(),
],
]
);
$this->add_group_control(
Group_Control_Image_Size::get_type(),
[
'name' => 'thumbnail', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `thumbnail_size` and `thumbnail_custom_dimension`.
'default' => 'full',
'separator' => 'none',
]
);
$this->add_control(
'title_text',
[
'label' => __( 'Title & Description', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => __( 'This is the heading', 'elementor' ),
'placeholder' => __( 'Enter your title', 'elementor' ),
'label_block' => true,
]
);
$this->add_control(
'description_text',
[
'label' => __( 'Content', 'elementor' ),
'type' => Controls_Manager::TEXTAREA,
'dynamic' => [
'active' => true,
],
'default' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
'placeholder' => __( 'Enter your description', 'elementor' ),
'separator' => 'none',
'rows' => 10,
'show_label' => false,
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'https://your-link.com', 'elementor' ),
'separator' => 'before',
]
);
$this->add_control(
'position',
[
'label' => __( 'Image Position', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'default' => 'top',
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-h-align-left',
],
'top' => [
'title' => __( 'Top', 'elementor' ),
'icon' => 'eicon-v-align-top',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-h-align-right',
],
],
'prefix_class' => 'elementor-position-',
'toggle' => false,
]
);
$this->add_control(
'title_size',
[
'label' => __( 'Title HTML Tag', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'h1' => 'H1',
'h2' => 'H2',
'h3' => 'H3',
'h4' => 'H4',
'h5' => 'H5',
'h6' => 'H6',
'div' => 'div',
'span' => 'span',
'p' => 'p',
],
'default' => 'h3',
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_image',
[
'label' => __( 'Image', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'image_space',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 15,
],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}.elementor-position-right .elementor-image-box-img' => 'margin-left: {{SIZE}}{{UNIT}};',
'{{WRAPPER}}.elementor-position-left .elementor-image-box-img' => 'margin-right: {{SIZE}}{{UNIT}};',
'{{WRAPPER}}.elementor-position-top .elementor-image-box-img' => 'margin-bottom: {{SIZE}}{{UNIT}};',
'(mobile){{WRAPPER}} .elementor-image-box-img' => 'margin-bottom: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'image_size',
[
'label' => __( 'Width', 'elementor' ) . ' (%)',
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 30,
'unit' => '%',
],
'tablet_default' => [
'unit' => '%',
],
'mobile_default' => [
'unit' => '%',
],
'size_units' => [ '%' ],
'range' => [
'%' => [
'min' => 5,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-image-box-wrapper .elementor-image-box-img' => 'width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'image_border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-image-box-wrapper img' => 'border-radius: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'hover_animation',
[
'label' => __( 'Hover Animation', 'elementor' ),
'type' => Controls_Manager::HOVER_ANIMATION,
]
);
$this->start_controls_tabs( 'image_effects' );
$this->start_controls_tab( 'normal',
[
'label' => __( 'Normal', 'elementor' ),
]
);
$this->add_group_control(
Group_Control_Css_Filter::get_type(),
[
'name' => 'css_filters',
'selector' => '{{WRAPPER}} .elementor-image-box-img img',
]
);
$this->add_control(
'image_opacity',
[
'label' => __( 'Opacity', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 1,
'min' => 0.10,
'step' => 0.01,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-image-box-img img' => 'opacity: {{SIZE}};',
],
]
);
$this->add_control(
'background_hover_transition',
[
'label' => __( 'Transition Duration', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 0.3,
],
'range' => [
'px' => [
'max' => 3,
'step' => 0.1,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-image-box-img img' => 'transition-duration: {{SIZE}}s',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'hover',
[
'label' => __( 'Hover', 'elementor' ),
]
);
$this->add_group_control(
Group_Control_Css_Filter::get_type(),
[
'name' => 'css_filters_hover',
'selector' => '{{WRAPPER}}:hover .elementor-image-box-img img',
]
);
$this->add_control(
'image_opacity_hover',
[
'label' => __( 'Opacity', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 1,
'min' => 0.10,
'step' => 0.01,
],
],
'selectors' => [
'{{WRAPPER}}:hover .elementor-image-box-img img' => 'opacity: {{SIZE}};',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
$this->start_controls_section(
'section_style_content',
[
'label' => __( 'Content', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'text_align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
],
],
'selectors' => [
'{{WRAPPER}} .elementor-image-box-wrapper' => 'text-align: {{VALUE}};',
],
]
);
$this->add_control(
'content_vertical_alignment',
[
'label' => __( 'Vertical Alignment', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'top' => __( 'Top', 'elementor' ),
'middle' => __( 'Middle', 'elementor' ),
'bottom' => __( 'Bottom', 'elementor' ),
],
'default' => 'top',
'prefix_class' => 'elementor-vertical-align-',
]
);
$this->add_control(
'heading_title',
[
'label' => __( 'Title', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_responsive_control(
'title_bottom_space',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-image-box-title' => 'margin-bottom: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-image-box-title' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'selector' => '{{WRAPPER}} .elementor-image-box-title',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'title_shadow',
'selector' => '{{WRAPPER}} .elementor-image-box-title',
]
);
$this->add_control(
'heading_description',
[
'label' => __( 'Description', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'description_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-image-box-description' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'description_typography',
'selector' => '{{WRAPPER}} .elementor-image-box-description',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'description_shadow',
'selector' => '{{WRAPPER}} .elementor-image-box-description',
]
);
$this->end_controls_section();
}
/**
* Render image box widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$has_content = ! Utils::is_empty( $settings['title_text'] ) || ! Utils::is_empty( $settings['description_text'] );
$html = '<div class="elementor-image-box-wrapper">';
if ( ! empty( $settings['link']['url'] ) ) {
$this->add_link_attributes( 'link', $settings['link'] );
}
if ( ! empty( $settings['image']['url'] ) ) {
$this->add_render_attribute( 'image', 'src', $settings['image']['url'] );
$this->add_render_attribute( 'image', 'alt', Control_Media::get_image_alt( $settings['image'] ) );
$this->add_render_attribute( 'image', 'title', Control_Media::get_image_title( $settings['image'] ) );
if ( $settings['hover_animation'] ) {
$this->add_render_attribute( 'image', 'class', 'elementor-animation-' . $settings['hover_animation'] );
}
$image_html = Group_Control_Image_Size::get_attachment_image_html( $settings, 'thumbnail', 'image' );
if ( ! empty( $settings['link']['url'] ) ) {
$image_html = '<a ' . $this->get_render_attribute_string( 'link' ) . '>' . $image_html . '</a>';
}
$html .= '<figure class="elementor-image-box-img">' . $image_html . '</figure>';
}
if ( $has_content ) {
$html .= '<div class="elementor-image-box-content">';
if ( ! Utils::is_empty( $settings['title_text'] ) ) {
$this->add_render_attribute( 'title_text', 'class', 'elementor-image-box-title' );
$this->add_inline_editing_attributes( 'title_text', 'none' );
$title_html = $settings['title_text'];
if ( ! empty( $settings['link']['url'] ) ) {
$title_html = '<a ' . $this->get_render_attribute_string( 'link' ) . '>' . $title_html . '</a>';
}
$html .= sprintf( '<%1$s %2$s>%3$s</%1$s>', Utils::validate_html_tag( $settings['title_size'] ), $this->get_render_attribute_string( 'title_text' ), $title_html );
}
if ( ! Utils::is_empty( $settings['description_text'] ) ) {
$this->add_render_attribute( 'description_text', 'class', 'elementor-image-box-description' );
$this->add_inline_editing_attributes( 'description_text' );
$html .= sprintf( '<p %1$s>%2$s</p>', $this->get_render_attribute_string( 'description_text' ), $settings['description_text'] );
}
$html .= '</div>';
}
$html .= '</div>';
echo $html;
}
/**
* Render image box widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<#
var html = '<div class="elementor-image-box-wrapper">';
if ( settings.image.url ) {
var image = {
id: settings.image.id,
url: settings.image.url,
size: settings.thumbnail_size,
dimension: settings.thumbnail_custom_dimension,
model: view.getEditModel()
};
var image_url = elementor.imagesManager.getImageUrl( image );
var imageHtml = '<img src="' + image_url + '" class="elementor-animation-' + settings.hover_animation + '" />';
if ( settings.link.url ) {
imageHtml = '<a href="' + settings.link.url + '">' + imageHtml + '</a>';
}
html += '<figure class="elementor-image-box-img">' + imageHtml + '</figure>';
}
var hasContent = !! ( settings.title_text || settings.description_text );
if ( hasContent ) {
html += '<div class="elementor-image-box-content">';
if ( settings.title_text ) {
var title_html = settings.title_text,
titleSizeTag = elementor.helpers.validateHTMLTag( settings.title_size );
if ( settings.link.url ) {
title_html = '<a href="' + settings.link.url + '">' + title_html + '</a>';
}
view.addRenderAttribute( 'title_text', 'class', 'elementor-image-box-title' );
view.addInlineEditingAttributes( 'title_text', 'none' );
html += '<' + titleSizeTag + ' ' + view.getRenderAttributeString( 'title_text' ) + '>' + title_html + '</' + titleSizeTag + '>';
}
if ( settings.description_text ) {
view.addRenderAttribute( 'description_text', 'class', 'elementor-image-box-description' );
view.addInlineEditingAttributes( 'description_text' );
html += '<p ' + view.getRenderAttributeString( 'description_text' ) + '>' + settings.description_text + '</p>';
}
html += '</div>';
}
html += '</div>';
print( html );
#>
<?php
}
}

View File

@@ -0,0 +1,851 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
/**
* Elementor image carousel widget.
*
* Elementor widget that displays a set of images in a rotating carousel or
* slider.
*
* @since 1.0.0
*/
class Widget_Image_Carousel extends Widget_Base {
/**
* Get widget name.
*
* Retrieve image carousel widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'image-carousel';
}
/**
* Get widget title.
*
* Retrieve image carousel widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Image Carousel', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve image carousel widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-slider-push';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'image', 'photo', 'visual', 'carousel', 'slider' ];
}
/**
* Register image carousel widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_image_carousel',
[
'label' => __( 'Image Carousel', 'elementor' ),
]
);
$this->add_control(
'carousel',
[
'label' => __( 'Add Images', 'elementor' ),
'type' => Controls_Manager::GALLERY,
'default' => [],
'show_label' => false,
'dynamic' => [
'active' => true,
],
]
);
$this->add_group_control(
Group_Control_Image_Size::get_type(),
[
'name' => 'thumbnail', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `thumbnail_size` and `thumbnail_custom_dimension`.
'separator' => 'none',
]
);
$slides_to_show = range( 1, 10 );
$slides_to_show = array_combine( $slides_to_show, $slides_to_show );
$this->add_responsive_control(
'slides_to_show',
[
'label' => __( 'Slides to Show', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'' => __( 'Default', 'elementor' ),
] + $slides_to_show,
'frontend_available' => true,
]
);
$this->add_responsive_control(
'slides_to_scroll',
[
'label' => __( 'Slides to Scroll', 'elementor' ),
'type' => Controls_Manager::SELECT,
'description' => __( 'Set how many slides are scrolled per swipe.', 'elementor' ),
'options' => [
'' => __( 'Default', 'elementor' ),
] + $slides_to_show,
'condition' => [
'slides_to_show!' => '1',
],
'frontend_available' => true,
]
);
$this->add_control(
'image_stretch',
[
'label' => __( 'Image Stretch', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'no',
'options' => [
'no' => __( 'No', 'elementor' ),
'yes' => __( 'Yes', 'elementor' ),
],
]
);
$this->add_control(
'navigation',
[
'label' => __( 'Navigation', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'both',
'options' => [
'both' => __( 'Arrows and Dots', 'elementor' ),
'arrows' => __( 'Arrows', 'elementor' ),
'dots' => __( 'Dots', 'elementor' ),
'none' => __( 'None', 'elementor' ),
],
'frontend_available' => true,
]
);
$this->add_control(
'link_to',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'none',
'options' => [
'none' => __( 'None', 'elementor' ),
'file' => __( 'Media File', 'elementor' ),
'custom' => __( 'Custom URL', 'elementor' ),
],
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'placeholder' => __( 'https://your-link.com', 'elementor' ),
'condition' => [
'link_to' => 'custom',
],
'show_label' => false,
]
);
$this->add_control(
'open_lightbox',
[
'label' => __( 'Lightbox', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'default',
'options' => [
'default' => __( 'Default', 'elementor' ),
'yes' => __( 'Yes', 'elementor' ),
'no' => __( 'No', 'elementor' ),
],
'condition' => [
'link_to' => 'file',
],
]
);
$this->add_control(
'caption_type',
[
'label' => __( 'Caption', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => '',
'options' => [
'' => __( 'None', 'elementor' ),
'title' => __( 'Title', 'elementor' ),
'caption' => __( 'Caption', 'elementor' ),
'description' => __( 'Description', 'elementor' ),
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_additional_options',
[
'label' => __( 'Additional Options', 'elementor' ),
]
);
$this->add_control(
'autoplay',
[
'label' => __( 'Autoplay', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'yes',
'options' => [
'yes' => __( 'Yes', 'elementor' ),
'no' => __( 'No', 'elementor' ),
],
'frontend_available' => true,
]
);
$this->add_control(
'pause_on_hover',
[
'label' => __( 'Pause on Hover', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'yes',
'options' => [
'yes' => __( 'Yes', 'elementor' ),
'no' => __( 'No', 'elementor' ),
],
'condition' => [
'autoplay' => 'yes',
],
'render_type' => 'none',
'frontend_available' => true,
]
);
$this->add_control(
'pause_on_interaction',
[
'label' => __( 'Pause on Interaction', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'yes',
'options' => [
'yes' => __( 'Yes', 'elementor' ),
'no' => __( 'No', 'elementor' ),
],
'condition' => [
'autoplay' => 'yes',
],
'frontend_available' => true,
]
);
$this->add_control(
'autoplay_speed',
[
'label' => __( 'Autoplay Speed', 'elementor' ),
'type' => Controls_Manager::NUMBER,
'default' => 5000,
'condition' => [
'autoplay' => 'yes',
],
'render_type' => 'none',
'frontend_available' => true,
]
);
// Loop requires a re-render so no 'render_type = none'
$this->add_control(
'infinite',
[
'label' => __( 'Infinite Loop', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'yes',
'options' => [
'yes' => __( 'Yes', 'elementor' ),
'no' => __( 'No', 'elementor' ),
],
'frontend_available' => true,
]
);
$this->add_control(
'effect',
[
'label' => __( 'Effect', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'slide',
'options' => [
'slide' => __( 'Slide', 'elementor' ),
'fade' => __( 'Fade', 'elementor' ),
],
'condition' => [
'slides_to_show' => '1',
],
'frontend_available' => true,
]
);
$this->add_control(
'speed',
[
'label' => __( 'Animation Speed', 'elementor' ),
'type' => Controls_Manager::NUMBER,
'default' => 500,
'render_type' => 'none',
'frontend_available' => true,
]
);
$this->add_control(
'direction',
[
'label' => __( 'Direction', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'ltr',
'options' => [
'ltr' => __( 'Left', 'elementor' ),
'rtl' => __( 'Right', 'elementor' ),
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_navigation',
[
'label' => __( 'Navigation', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'navigation' => [ 'arrows', 'dots', 'both' ],
],
]
);
$this->add_control(
'heading_style_arrows',
[
'label' => __( 'Arrows', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
'condition' => [
'navigation' => [ 'arrows', 'both' ],
],
]
);
$this->add_control(
'arrows_position',
[
'label' => __( 'Position', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'inside',
'options' => [
'inside' => __( 'Inside', 'elementor' ),
'outside' => __( 'Outside', 'elementor' ),
],
'prefix_class' => 'elementor-arrows-position-',
'condition' => [
'navigation' => [ 'arrows', 'both' ],
],
]
);
$this->add_control(
'arrows_size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 20,
'max' => 60,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-swiper-button.elementor-swiper-button-prev, {{WRAPPER}} .elementor-swiper-button.elementor-swiper-button-next' => 'font-size: {{SIZE}}{{UNIT}};',
],
'condition' => [
'navigation' => [ 'arrows', 'both' ],
],
]
);
$this->add_control(
'arrows_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-swiper-button.elementor-swiper-button-prev, {{WRAPPER}} .elementor-swiper-button.elementor-swiper-button-next' => 'color: {{VALUE}};',
],
'condition' => [
'navigation' => [ 'arrows', 'both' ],
],
]
);
$this->add_control(
'heading_style_dots',
[
'label' => __( 'Dots', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
'condition' => [
'navigation' => [ 'dots', 'both' ],
],
]
);
$this->add_control(
'dots_position',
[
'label' => __( 'Position', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'outside',
'options' => [
'outside' => __( 'Outside', 'elementor' ),
'inside' => __( 'Inside', 'elementor' ),
],
'prefix_class' => 'elementor-pagination-position-',
'condition' => [
'navigation' => [ 'dots', 'both' ],
],
]
);
$this->add_control(
'dots_size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 5,
'max' => 10,
],
],
'selectors' => [
'{{WRAPPER}} .swiper-pagination-bullet' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
],
'condition' => [
'navigation' => [ 'dots', 'both' ],
],
]
);
$this->add_control(
'dots_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .swiper-pagination-bullet' => 'background: {{VALUE}};',
],
'condition' => [
'navigation' => [ 'dots', 'both' ],
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_image',
[
'label' => __( 'Image', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'gallery_vertical_align',
[
'label' => __( 'Vertical Align', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'flex-start' => [
'title' => __( 'Start', 'elementor' ),
'icon' => 'eicon-v-align-top',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-v-align-middle',
],
'flex-end' => [
'title' => __( 'End', 'elementor' ),
'icon' => 'eicon-v-align-bottom',
],
],
'condition' => [
'slides_to_show!' => '1',
],
'selectors' => [
'{{WRAPPER}} .swiper-wrapper' => 'display: flex; align-items: {{VALUE}};',
],
]
);
$this->add_control(
'image_spacing',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'' => __( 'Default', 'elementor' ),
'custom' => __( 'Custom', 'elementor' ),
],
'default' => '',
'condition' => [
'slides_to_show!' => '1',
],
]
);
$this->add_control(
'image_spacing_custom',
[
'label' => __( 'Image Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 100,
],
],
'default' => [
'size' => 20,
],
'show_label' => false,
'condition' => [
'image_spacing' => 'custom',
'slides_to_show!' => '1',
],
'frontend_available' => true,
'render_type' => 'none',
'separator' => 'after',
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'image_border',
'selector' => '{{WRAPPER}} .elementor-image-carousel-wrapper .elementor-image-carousel .swiper-slide-image',
]
);
$this->add_control(
'image_border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-image-carousel-wrapper .elementor-image-carousel .swiper-slide-image' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_caption',
[
'label' => __( 'Caption', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'caption_type!' => '',
],
]
);
$this->add_control(
'caption_align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
],
],
'default' => 'center',
'selectors' => [
'{{WRAPPER}} .elementor-image-carousel-caption' => 'text-align: {{VALUE}};',
],
]
);
$this->add_control(
'caption_text_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-image-carousel-caption' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'caption_typography',
'global' => [
'default' => Global_Colors::COLOR_ACCENT,
],
'selector' => '{{WRAPPER}} .elementor-image-carousel-caption',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'caption_shadow',
'selector' => '{{WRAPPER}} .elementor-image-carousel-caption',
]
);
$this->end_controls_section();
}
/**
* Render image carousel widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
if ( empty( $settings['carousel'] ) ) {
return;
}
$slides = [];
foreach ( $settings['carousel'] as $index => $attachment ) {
$image_url = Group_Control_Image_Size::get_attachment_image_src( $attachment['id'], 'thumbnail', $settings );
$image_html = '<img class="swiper-slide-image" src="' . esc_attr( $image_url ) . '" alt="' . esc_attr( Control_Media::get_image_alt( $attachment ) ) . '" />';
$link_tag = '';
$link = $this->get_link_url( $attachment, $settings );
if ( $link ) {
$link_key = 'link_' . $index;
$this->add_lightbox_data_attributes( $link_key, $attachment['id'], $settings['open_lightbox'], $this->get_id() );
if ( Plugin::$instance->editor->is_edit_mode() ) {
$this->add_render_attribute( $link_key, [
'class' => 'elementor-clickable',
] );
}
$this->add_link_attributes( $link_key, $link );
$link_tag = '<a ' . $this->get_render_attribute_string( $link_key ) . '>';
}
$image_caption = $this->get_image_caption( $attachment );
$slide_html = '<div class="swiper-slide">' . $link_tag . '<figure class="swiper-slide-inner">' . $image_html;
if ( ! empty( $image_caption ) ) {
$slide_html .= '<figcaption class="elementor-image-carousel-caption">' . $image_caption . '</figcaption>';
}
$slide_html .= '</figure>';
if ( $link ) {
$slide_html .= '</a>';
}
$slide_html .= '</div>';
$slides[] = $slide_html;
}
if ( empty( $slides ) ) {
return;
}
$this->add_render_attribute( [
'carousel' => [
'class' => 'elementor-image-carousel swiper-wrapper',
],
'carousel-wrapper' => [
'class' => 'elementor-image-carousel-wrapper swiper-container',
'dir' => $settings['direction'],
],
] );
$show_dots = ( in_array( $settings['navigation'], [ 'dots', 'both' ] ) );
$show_arrows = ( in_array( $settings['navigation'], [ 'arrows', 'both' ] ) );
if ( 'yes' === $settings['image_stretch'] ) {
$this->add_render_attribute( 'carousel', 'class', 'swiper-image-stretch' );
}
$slides_count = count( $settings['carousel'] );
?>
<div <?php echo $this->get_render_attribute_string( 'carousel-wrapper' ); ?>>
<div <?php echo $this->get_render_attribute_string( 'carousel' ); ?>>
<?php echo implode( '', $slides ); ?>
</div>
<?php if ( 1 < $slides_count ) : ?>
<?php if ( $show_dots ) : ?>
<div class="swiper-pagination"></div>
<?php endif; ?>
<?php if ( $show_arrows ) : ?>
<div class="elementor-swiper-button elementor-swiper-button-prev">
<i class="eicon-chevron-left" aria-hidden="true"></i>
<span class="elementor-screen-only"><?php _e( 'Previous', 'elementor' ); ?></span>
</div>
<div class="elementor-swiper-button elementor-swiper-button-next">
<i class="eicon-chevron-right" aria-hidden="true"></i>
<span class="elementor-screen-only"><?php _e( 'Next', 'elementor' ); ?></span>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<?php
}
/**
* Retrieve image carousel link URL.
*
* @since 1.0.0
* @access private
*
* @param array $attachment
* @param object $instance
*
* @return array|string|false An array/string containing the attachment URL, or false if no link.
*/
private function get_link_url( $attachment, $instance ) {
if ( 'none' === $instance['link_to'] ) {
return false;
}
if ( 'custom' === $instance['link_to'] ) {
if ( empty( $instance['link']['url'] ) ) {
return false;
}
return $instance['link'];
}
return [
'url' => wp_get_attachment_url( $attachment['id'] ),
];
}
/**
* Retrieve image carousel caption.
*
* @since 1.2.0
* @access private
*
* @param array $attachment
*
* @return string The caption of the image.
*/
private function get_image_caption( $attachment ) {
$caption_type = $this->get_settings_for_display( 'caption_type' );
if ( empty( $caption_type ) ) {
return '';
}
$attachment_post = get_post( $attachment['id'] );
if ( 'caption' === $caption_type ) {
return $attachment_post->post_excerpt;
}
if ( 'title' === $caption_type ) {
return $attachment_post->post_title;
}
return $attachment_post->post_content;
}
}

View File

@@ -0,0 +1,392 @@
<?php
namespace Elementor;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor image gallery widget.
*
* Elementor widget that displays a set of images in an aligned grid.
*
* @since 1.0.0
*/
class Widget_Image_Gallery extends Widget_Base {
/**
* Get widget name.
*
* Retrieve image gallery widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'image-gallery';
}
/**
* Get widget title.
*
* Retrieve image gallery widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Basic Gallery', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve image gallery widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-gallery-grid';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'image', 'photo', 'visual', 'gallery' ];
}
/**
* Register image gallery widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_gallery',
[
'label' => __( 'Image Gallery', 'elementor' ),
]
);
$this->add_control(
'wp_gallery',
[
'label' => __( 'Add Images', 'elementor' ),
'type' => Controls_Manager::GALLERY,
'show_label' => false,
'dynamic' => [
'active' => true,
],
]
);
$this->add_group_control(
Group_Control_Image_Size::get_type(),
[
'name' => 'thumbnail', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `thumbnail_size` and `thumbnail_custom_dimension`.
'exclude' => [ 'custom' ],
'separator' => 'none',
]
);
$gallery_columns = range( 1, 10 );
$gallery_columns = array_combine( $gallery_columns, $gallery_columns );
$this->add_control(
'gallery_columns',
[
'label' => __( 'Columns', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 4,
'options' => $gallery_columns,
]
);
$this->add_control(
'gallery_link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'file',
'options' => [
'file' => __( 'Media File', 'elementor' ),
'attachment' => __( 'Attachment Page', 'elementor' ),
'none' => __( 'None', 'elementor' ),
],
]
);
$this->add_control(
'open_lightbox',
[
'label' => __( 'Lightbox', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'default',
'options' => [
'default' => __( 'Default', 'elementor' ),
'yes' => __( 'Yes', 'elementor' ),
'no' => __( 'No', 'elementor' ),
],
'condition' => [
'gallery_link' => 'file',
],
]
);
$this->add_control(
'gallery_rand',
[
'label' => __( 'Order By', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'' => __( 'Default', 'elementor' ),
'rand' => __( 'Random', 'elementor' ),
],
'default' => '',
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_gallery_images',
[
'label' => __( 'Images', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'image_spacing',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'' => __( 'Default', 'elementor' ),
'custom' => __( 'Custom', 'elementor' ),
],
'prefix_class' => 'gallery-spacing-',
'default' => '',
]
);
$columns_margin = is_rtl() ? '0 0 -{{SIZE}}{{UNIT}} -{{SIZE}}{{UNIT}};' : '0 -{{SIZE}}{{UNIT}} -{{SIZE}}{{UNIT}} 0;';
$columns_padding = is_rtl() ? '0 0 {{SIZE}}{{UNIT}} {{SIZE}}{{UNIT}};' : '0 {{SIZE}}{{UNIT}} {{SIZE}}{{UNIT}} 0;';
$this->add_control(
'image_spacing_custom',
[
'label' => __( 'Image Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'show_label' => false,
'range' => [
'px' => [
'max' => 100,
],
],
'default' => [
'size' => 15,
],
'selectors' => [
'{{WRAPPER}} .gallery-item' => 'padding:' . $columns_padding,
'{{WRAPPER}} .gallery' => 'margin: ' . $columns_margin,
],
'condition' => [
'image_spacing' => 'custom',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'image_border',
'selector' => '{{WRAPPER}} .gallery-item img',
'separator' => 'before',
]
);
$this->add_control(
'image_border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .gallery-item img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_caption',
[
'label' => __( 'Caption', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'gallery_display_caption',
[
'label' => __( 'Display', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => '',
'options' => [
'' => __( 'Show', 'elementor' ),
'none' => __( 'Hide', 'elementor' ),
],
'selectors' => [
'{{WRAPPER}} .gallery-item .gallery-caption' => 'display: {{VALUE}};',
],
]
);
$this->add_control(
'align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
],
],
'default' => 'center',
'selectors' => [
'{{WRAPPER}} .gallery-item .gallery-caption' => 'text-align: {{VALUE}};',
],
'condition' => [
'gallery_display_caption' => '',
],
]
);
$this->add_control(
'text_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .gallery-item .gallery-caption' => 'color: {{VALUE}};',
],
'condition' => [
'gallery_display_caption' => '',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_ACCENT,
],
'selector' => '{{WRAPPER}} .gallery-item .gallery-caption',
'condition' => [
'gallery_display_caption' => '',
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'caption_shadow',
'selector' => '{{WRAPPER}} .gallery-item .gallery-caption',
]
);
$this->end_controls_section();
}
/**
* Render image gallery widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
if ( ! $settings['wp_gallery'] ) {
return;
}
$ids = wp_list_pluck( $settings['wp_gallery'], 'id' );
$this->add_render_attribute( 'shortcode', 'ids', implode( ',', $ids ) );
$this->add_render_attribute( 'shortcode', 'size', $settings['thumbnail_size'] );
if ( $settings['gallery_columns'] ) {
$this->add_render_attribute( 'shortcode', 'columns', $settings['gallery_columns'] );
}
if ( $settings['gallery_link'] ) {
$this->add_render_attribute( 'shortcode', 'link', $settings['gallery_link'] );
}
if ( ! empty( $settings['gallery_rand'] ) ) {
$this->add_render_attribute( 'shortcode', 'orderby', $settings['gallery_rand'] );
}
?>
<div class="elementor-image-gallery">
<?php
add_filter( 'wp_get_attachment_link', [ $this, 'add_lightbox_data_to_image_link' ], 10, 2 );
echo do_shortcode( '[gallery ' . $this->get_render_attribute_string( 'shortcode' ) . ']' );
remove_filter( 'wp_get_attachment_link', [ $this, 'add_lightbox_data_to_image_link' ] );
?>
</div>
<?php
}
}

View File

@@ -0,0 +1,848 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor image widget.
*
* Elementor widget that displays an image into the page.
*
* @since 1.0.0
*/
class Widget_Image extends Widget_Base {
/**
* Get widget name.
*
* Retrieve image widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'image';
}
/**
* Get widget title.
*
* Retrieve image widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Image', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve image widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-image';
}
/**
* Get widget categories.
*
* Retrieve the list of categories the image widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* @since 2.0.0
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'basic' ];
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'image', 'photo', 'visual' ];
}
/**
* Register image widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_image',
[
'label' => __( 'Image', 'elementor' ),
]
);
$this->add_control(
'image',
[
'label' => __( 'Choose Image', 'elementor' ),
'type' => Controls_Manager::MEDIA,
'dynamic' => [
'active' => true,
],
'default' => [
'url' => Utils::get_placeholder_image_src(),
],
]
);
$this->add_group_control(
Group_Control_Image_Size::get_type(),
[
'name' => 'image', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `image_size` and `image_custom_dimension`.
'default' => 'large',
'separator' => 'none',
]
);
$this->add_responsive_control(
'align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => 'text-align: {{VALUE}};',
],
]
);
$this->add_control(
'caption_source',
[
'label' => __( 'Caption', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'none' => __( 'None', 'elementor' ),
'attachment' => __( 'Attachment Caption', 'elementor' ),
'custom' => __( 'Custom Caption', 'elementor' ),
],
'default' => 'none',
]
);
$this->add_control(
'caption',
[
'label' => __( 'Custom Caption', 'elementor' ),
'type' => Controls_Manager::TEXT,
'default' => '',
'placeholder' => __( 'Enter your image caption', 'elementor' ),
'condition' => [
'caption_source' => 'custom',
],
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'link_to',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'none',
'options' => [
'none' => __( 'None', 'elementor' ),
'file' => __( 'Media File', 'elementor' ),
'custom' => __( 'Custom URL', 'elementor' ),
],
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'https://your-link.com', 'elementor' ),
'condition' => [
'link_to' => 'custom',
],
'show_label' => false,
]
);
$this->add_control(
'open_lightbox',
[
'label' => __( 'Lightbox', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'default',
'options' => [
'default' => __( 'Default', 'elementor' ),
'yes' => __( 'Yes', 'elementor' ),
'no' => __( 'No', 'elementor' ),
],
'condition' => [
'link_to' => 'file',
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_image',
[
'label' => __( 'Image', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'width',
[
'label' => __( 'Width', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'unit' => '%',
],
'tablet_default' => [
'unit' => '%',
],
'mobile_default' => [
'unit' => '%',
],
'size_units' => [ '%', 'px', 'vw' ],
'range' => [
'%' => [
'min' => 1,
'max' => 100,
],
'px' => [
'min' => 1,
'max' => 1000,
],
'vw' => [
'min' => 1,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} img' => 'width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'space',
[
'label' => __( 'Max Width', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'unit' => '%',
],
'tablet_default' => [
'unit' => '%',
],
'mobile_default' => [
'unit' => '%',
],
'size_units' => [ '%', 'px', 'vw' ],
'range' => [
'%' => [
'min' => 1,
'max' => 100,
],
'px' => [
'min' => 1,
'max' => 1000,
],
'vw' => [
'min' => 1,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} img' => 'max-width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'height',
[
'label' => __( 'Height', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'unit' => 'px',
],
'tablet_default' => [
'unit' => 'px',
],
'mobile_default' => [
'unit' => 'px',
],
'size_units' => [ 'px', 'vh' ],
'range' => [
'px' => [
'min' => 1,
'max' => 500,
],
'vh' => [
'min' => 1,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} img' => 'height: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'object-fit',
[
'label' => __( 'Object Fit', 'elementor' ),
'type' => Controls_Manager::SELECT,
'condition' => [
'height[size]!' => '',
],
'options' => [
'' => __( 'Default', 'elementor' ),
'fill' => __( 'Fill', 'elementor' ),
'cover' => __( 'Cover', 'elementor' ),
'contain' => __( 'Contain', 'elementor' ),
],
'default' => '',
'selectors' => [
'{{WRAPPER}} img' => 'object-fit: {{VALUE}};',
],
]
);
$this->add_control(
'separator_panel_style',
[
'type' => Controls_Manager::DIVIDER,
'style' => 'thick',
]
);
$this->start_controls_tabs( 'image_effects' );
$this->start_controls_tab( 'normal',
[
'label' => __( 'Normal', 'elementor' ),
]
);
$this->add_control(
'opacity',
[
'label' => __( 'Opacity', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 1,
'min' => 0.10,
'step' => 0.01,
],
],
'selectors' => [
'{{WRAPPER}} img' => 'opacity: {{SIZE}};',
],
]
);
$this->add_group_control(
Group_Control_Css_Filter::get_type(),
[
'name' => 'css_filters',
'selector' => '{{WRAPPER}} img',
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'hover',
[
'label' => __( 'Hover', 'elementor' ),
]
);
$this->add_control(
'opacity_hover',
[
'label' => __( 'Opacity', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 1,
'min' => 0.10,
'step' => 0.01,
],
],
'selectors' => [
'{{WRAPPER}}:hover img' => 'opacity: {{SIZE}};',
],
]
);
$this->add_group_control(
Group_Control_Css_Filter::get_type(),
[
'name' => 'css_filters_hover',
'selector' => '{{WRAPPER}}:hover img',
]
);
$this->add_control(
'background_hover_transition',
[
'label' => __( 'Transition Duration', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'max' => 3,
'step' => 0.1,
],
],
'selectors' => [
'{{WRAPPER}} img' => 'transition-duration: {{SIZE}}s',
],
]
);
$this->add_control(
'hover_animation',
[
'label' => __( 'Hover Animation', 'elementor' ),
'type' => Controls_Manager::HOVER_ANIMATION,
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'image_border',
'selector' => '{{WRAPPER}} img',
'separator' => 'before',
]
);
$this->add_responsive_control(
'image_border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'image_box_shadow',
'exclude' => [
'box_shadow_position',
],
'selector' => '{{WRAPPER}} img',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_caption',
[
'label' => __( 'Caption', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'caption_source!' => 'none',
],
]
);
$this->add_control(
'caption_align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
],
],
'default' => '',
'selectors' => [
'{{WRAPPER}} .widget-image-caption' => 'text-align: {{VALUE}};',
],
]
);
$this->add_control(
'text_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}} .widget-image-caption' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
]
);
$this->add_control(
'caption_background_color',
[
'label' => __( 'Background Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .widget-image-caption' => 'background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'caption_typography',
'selector' => '{{WRAPPER}} .widget-image-caption',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'caption_text_shadow',
'selector' => '{{WRAPPER}} .widget-image-caption',
]
);
$this->add_responsive_control(
'caption_space',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .widget-image-caption' => 'margin-top: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
}
/**
* Check if the current widget has caption
*
* @access private
* @since 2.3.0
*
* @param array $settings
*
* @return boolean
*/
private function has_caption( $settings ) {
return ( ! empty( $settings['caption_source'] ) && 'none' !== $settings['caption_source'] );
}
/**
* Get the caption for current widget.
*
* @access private
* @since 2.3.0
* @param $settings
*
* @return string
*/
private function get_caption( $settings ) {
$caption = '';
if ( ! empty( $settings['caption_source'] ) ) {
switch ( $settings['caption_source'] ) {
case 'attachment':
$caption = wp_get_attachment_caption( $settings['image']['id'] );
break;
case 'custom':
$caption = ! Utils::is_empty( $settings['caption'] ) ? $settings['caption'] : '';
}
}
return $caption;
}
/**
* Render image widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
if ( empty( $settings['image']['url'] ) ) {
return;
}
if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) {
$this->add_render_attribute( 'wrapper', 'class', 'elementor-image' );
}
$has_caption = $this->has_caption( $settings );
$link = $this->get_link_url( $settings );
if ( $link ) {
$this->add_link_attributes( 'link', $link );
if ( Plugin::$instance->editor->is_edit_mode() ) {
$this->add_render_attribute( 'link', [
'class' => 'elementor-clickable',
] );
}
if ( 'custom' !== $settings['link_to'] ) {
$this->add_lightbox_data_attributes( 'link', $settings['image']['id'], $settings['open_lightbox'] );
}
} ?>
<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
<div <?php echo $this->get_render_attribute_string( 'wrapper' ); ?>>
<?php } ?>
<?php if ( $has_caption ) : ?>
<figure class="wp-caption">
<?php endif; ?>
<?php if ( $link ) : ?>
<a <?php echo $this->get_render_attribute_string( 'link' ); ?>>
<?php endif; ?>
<?php echo Group_Control_Image_Size::get_attachment_image_html( $settings ); ?>
<?php if ( $link ) : ?>
</a>
<?php endif; ?>
<?php if ( $has_caption ) : ?>
<figcaption class="widget-image-caption wp-caption-text"><?php echo $this->get_caption( $settings ); ?></figcaption>
<?php endif; ?>
<?php if ( $has_caption ) : ?>
</figure>
<?php endif; ?>
<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
</div>
<?php } ?>
<?php
}
/**
* Render image widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<# if ( settings.image.url ) {
var image = {
id: settings.image.id,
url: settings.image.url,
size: settings.image_size,
dimension: settings.image_custom_dimension,
model: view.getEditModel()
};
var image_url = elementor.imagesManager.getImageUrl( image );
if ( ! image_url ) {
return;
}
var hasCaption = function() {
if( ! settings.caption_source || 'none' === settings.caption_source ) {
return false;
}
return true;
}
var ensureAttachmentData = function( id ) {
if ( 'undefined' === typeof wp.media.attachment( id ).get( 'caption' ) ) {
wp.media.attachment( id ).fetch().then( function( data ) {
view.render();
} );
}
}
var getAttachmentCaption = function( id ) {
if ( ! id ) {
return '';
}
ensureAttachmentData( id );
return wp.media.attachment( id ).get( 'caption' );
}
var getCaption = function() {
if ( ! hasCaption() ) {
return '';
}
return 'custom' === settings.caption_source ? settings.caption : getAttachmentCaption( settings.image.id );
}
var link_url;
if ( 'custom' === settings.link_to ) {
link_url = settings.link.url;
}
if ( 'file' === settings.link_to ) {
link_url = settings.image.url;
}
<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
#><div class="elementor-image{{ settings.shape ? ' elementor-image-shape-' + settings.shape : '' }}"><#
<?php } ?>
var imgClass = '';
if ( '' !== settings.hover_animation ) {
imgClass = 'elementor-animation-' + settings.hover_animation;
}
if ( hasCaption() ) {
#><figure class="wp-caption"><#
}
if ( link_url ) {
#><a class="elementor-clickable" data-elementor-open-lightbox="{{ settings.open_lightbox }}" href="{{ link_url }}"><#
}
#><img src="{{ image_url }}" class="{{ imgClass }}" /><#
if ( link_url ) {
#></a><#
}
if ( hasCaption() ) {
#><figcaption class="widget-image-caption wp-caption-text">{{{ getCaption() }}}</figcaption><#
}
if ( hasCaption() ) {
#></figure><#
}
<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
#></div><#
<?php } ?>
} #>
<?php
}
/**
* Retrieve image widget link URL.
*
* @since 1.0.0
* @access private
*
* @param array $settings
*
* @return array|string|false An array/string containing the link URL, or false if no link.
*/
private function get_link_url( $settings ) {
if ( 'none' === $settings['link_to'] ) {
return false;
}
if ( 'custom' === $settings['link_to'] ) {
if ( empty( $settings['link']['url'] ) ) {
return false;
}
return $settings['link'];
}
return [
'url' => $settings['image']['url'],
];
}
}

View File

@@ -0,0 +1,147 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor menu anchor widget.
*
* Elementor widget that allows to link and menu to a specific position on the
* page.
*
* @since 1.0.0
*/
class Widget_Menu_Anchor extends Widget_Base {
/**
* Get widget name.
*
* Retrieve menu anchor widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'menu-anchor';
}
/**
* Get widget title.
*
* Retrieve menu anchor widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Menu Anchor', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve menu anchor widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-anchor';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'menu', 'anchor', 'link' ];
}
/**
* Register menu anchor widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_anchor',
[
'label' => __( 'Anchor', 'elementor' ),
]
);
$this->add_control(
'anchor',
[
'label' => __( 'The ID of Menu Anchor.', 'elementor' ),
'type' => Controls_Manager::TEXT,
'placeholder' => __( 'For Example: About', 'elementor' ),
'description' => __( 'This ID will be the CSS ID you will have to use in your own page, Without #.', 'elementor' ),
'label_block' => true,
]
);
$this->add_control(
'anchor_note',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => sprintf( __( 'Note: The ID link ONLY accepts these chars: %s', 'elementor' ), '`A-Z, a-z, 0-9, _ , -`' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-warning',
]
);
$this->end_controls_section();
}
/**
* Render menu anchor widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$anchor = $this->get_settings_for_display( 'anchor' );
if ( ! empty( $anchor ) ) {
$this->add_render_attribute( 'inner', 'id', sanitize_html_class( $anchor ) );
}
$this->add_render_attribute( 'inner', 'class', 'elementor-menu-anchor' );
?>
<div <?php echo $this->get_render_attribute_string( 'inner' ); ?>></div>
<?php
}
/**
* Render menu anchor widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<div class="elementor-menu-anchor"{{{ settings.anchor ? ' id="' + settings.anchor + '"' : '' }}}></div>
<?php
}
}

View File

@@ -0,0 +1,425 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor progress widget.
*
* Elementor widget that displays an escalating progress bar.
*
* @since 1.0.0
*/
class Widget_Progress extends Widget_Base {
/**
* Get widget name.
*
* Retrieve progress widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'progress';
}
/**
* Get widget title.
*
* Retrieve progress widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Progress Bar', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve progress widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-skill-bar';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'progress', 'bar' ];
}
/**
* Register progress widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_progress',
[
'label' => __( 'Progress Bar', 'elementor' ),
]
);
$this->add_control(
'title',
[
'label' => __( 'Title', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'Enter your title', 'elementor' ),
'default' => __( 'My Skill', 'elementor' ),
'label_block' => true,
]
);
$this->add_control(
'progress_type',
[
'label' => __( 'Type', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => '',
'options' => [
'' => __( 'Default', 'elementor' ),
'info' => __( 'Info', 'elementor' ),
'success' => __( 'Success', 'elementor' ),
'warning' => __( 'Warning', 'elementor' ),
'danger' => __( 'Danger', 'elementor' ),
],
]
);
$this->add_control(
'percent',
[
'label' => __( 'Percentage', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 50,
'unit' => '%',
],
'dynamic' => [
'active' => true,
],
]
);
$this->add_control( 'display_percentage', [
'label' => __( 'Display Percentage', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'show',
'options' => [
'show' => __( 'Show', 'elementor' ),
'hide' => __( 'Hide', 'elementor' ),
],
] );
$this->add_control(
'inner_text',
[
'label' => __( 'Inner Text', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'e.g. Web Designer', 'elementor' ),
'default' => __( 'Web Designer', 'elementor' ),
'label_block' => true,
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_progress_style',
[
'label' => __( 'Progress Bar', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'bar_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
'selectors' => [
'{{WRAPPER}} .elementor-progress-wrapper .elementor-progress-bar' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'bar_bg_color',
[
'label' => __( 'Background Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-progress-wrapper' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'bar_height',
[
'label' => __( 'Height', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'selectors' => [
'{{WRAPPER}} .elementor-progress-bar' => 'height: {{SIZE}}{{UNIT}}; line-height: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'bar_border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-progress-wrapper' => 'border-radius: {{SIZE}}{{UNIT}}; overflow: hidden;',
],
]
);
$this->add_control(
'inner_text_heading',
[
'label' => __( 'Inner Text', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'bar_inline_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-progress-bar' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'bar_inner_typography',
'selector' => '{{WRAPPER}} .elementor-progress-bar',
'exclude' => [
'line_height',
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'bar_inner_shadow',
'selector' => '{{WRAPPER}} .elementor-progress-bar',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_title',
[
'label' => __( 'Title Style', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-title' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'typography',
'selector' => '{{WRAPPER}} .elementor-title',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'title_shadow',
'selector' => '{{WRAPPER}} .elementor-title',
]
);
$this->end_controls_section();
}
/**
* Render progress widget output on the frontend.
* Make sure value does no exceed 100%.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$progress_percentage = is_numeric( $settings['percent']['size'] ) ? $settings['percent']['size'] : '0';
if ( 100 < $progress_percentage ) {
$progress_percentage = 100;
}
$this->add_render_attribute( 'title', [
'class' => 'elementor-title',
]);
$this->add_inline_editing_attributes( 'title' );
$this->add_render_attribute( 'wrapper', [
'class' => 'elementor-progress-wrapper',
'role' => 'progressbar',
'aria-valuemin' => '0',
'aria-valuemax' => '100',
'aria-valuenow' => $progress_percentage,
'aria-valuetext' => $settings['inner_text'],
] );
if ( ! empty( $settings['progress_type'] ) ) {
$this->add_render_attribute( 'wrapper', 'class', 'progress-' . $settings['progress_type'] );
}
$this->add_render_attribute( 'progress-bar', [
'class' => 'elementor-progress-bar',
'data-max' => $progress_percentage,
] );
$this->add_render_attribute( 'inner_text', [
'class' => 'elementor-progress-text',
] );
$this->add_inline_editing_attributes( 'inner_text' );
if ( ! Utils::is_empty( $settings['title'] ) ) { ?>
<span <?php echo $this->get_render_attribute_string( 'title' ); ?>><?php echo $settings['title']; ?></span>
<?php } ?>
<div <?php echo $this->get_render_attribute_string( 'wrapper' ); ?>>
<div <?php echo $this->get_render_attribute_string( 'progress-bar' ); ?>>
<span <?php echo $this->get_render_attribute_string( 'inner_text' ); ?>><?php echo $settings['inner_text']; ?></span>
<?php if ( 'hide' !== $settings['display_percentage'] ) { ?>
<span class="elementor-progress-percentage"><?php echo $progress_percentage; ?>%</span>
<?php } ?>
</div>
</div>
<?php
}
/**
* Render progress widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<#
let progress_percentage = 0;
if ( ! isNaN( settings.percent.size ) ) {
progress_percentage = 100 < settings.percent.size ? 100 : settings.percent.size;
}
view.addRenderAttribute( 'title', {
'class': 'elementor-title'
} );
view.addInlineEditingAttributes( 'title' );
view.addRenderAttribute( 'progressWrapper', {
'class': [ 'elementor-progress-wrapper', 'progress-' + settings.progress_type ],
'role': 'progressbar',
'aria-valuemin': '0',
'aria-valuemax': '100',
'aria-valuenow': progress_percentage,
'aria-valuetext': settings.inner_text
} );
view.addRenderAttribute( 'inner_text', {
'class': 'elementor-progress-text'
} );
view.addInlineEditingAttributes( 'inner_text' );
#>
<# if ( settings.title ) { #>
<span {{{ view.getRenderAttributeString( 'title' ) }}}>{{{ settings.title }}}</span><#
} #>
<div {{{ view.getRenderAttributeString( 'progressWrapper' ) }}}>
<div class="elementor-progress-bar" data-max="{{ progress_percentage }}">
<span {{{ view.getRenderAttributeString( 'inner_text' ) }}}>{{{ settings.inner_text }}}</span>
<# if ( 'hide' !== settings.display_percentage ) { #>
<span class="elementor-progress-percentage">{{{ progress_percentage }}}%</span>
<# } #>
</div>
</div>
<?php
}
}

View File

@@ -0,0 +1,135 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor HTML widget.
*
* Elementor widget that insert a custom HTML code into the page.
*
*/
class Widget_Read_More extends Widget_Base {
/**
* Get widget name.
*
* Retrieve Read More widget name.
*
* @since 2.4.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'read-more';
}
/**
* Get widget title.
*
* Retrieve Read More widget title.
*
* @since 2.4.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Read More', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve Read More widget icon.
*
* @since 2.4.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-post-excerpt';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.4.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'read', 'more', 'tag', 'excerpt' ];
}
/**
* Register HTML widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_title',
[
'label' => __( 'Read More', 'elementor' ),
]
);
$default_link_text = apply_filters( 'elementor/widgets/read_more/default_link_text', __( 'Continue reading', 'elementor' ) );
$this->add_control(
'theme_support',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => sprintf( __( 'Note: This widget only affects themes that use `%s` in archive pages.', 'elementor' ), 'the_content' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-warning',
]
);
$this->add_control(
'link_text',
[
'label' => __( 'Read More Text', 'elementor' ),
'placeholder' => $default_link_text,
'default' => $default_link_text,
]
);
$this->end_controls_section();
}
/**
* Render Read More widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @access protected
*/
protected function render() {
printf( '<!--more %s-->', $this->get_settings_for_display( 'link_text' ) );
}
/**
* Render Read More widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<!--more {{ settings.link_text }}-->
<?php
}
}

View File

@@ -0,0 +1,158 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor shortcode widget.
*
* Elementor widget that insert any shortcodes into the page.
*
* @since 1.0.0
*/
class Widget_Shortcode extends Widget_Base {
/**
* Get widget name.
*
* Retrieve shortcode widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'shortcode';
}
/**
* Get widget title.
*
* Retrieve shortcode widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Shortcode', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve shortcode widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-shortcode';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'shortcode', 'code' ];
}
/**
* Whether the reload preview is required or not.
*
* Used to determine whether the reload preview is required.
*
* @since 1.0.0
* @access public
*
* @return bool Whether the reload preview is required.
*/
public function is_reload_preview_required() {
return true;
}
/**
* Register shortcode widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_shortcode',
[
'label' => __( 'Shortcode', 'elementor' ),
]
);
$this->add_control(
'shortcode',
[
'label' => __( 'Enter your shortcode', 'elementor' ),
'type' => Controls_Manager::TEXTAREA,
'dynamic' => [
'active' => true,
],
'placeholder' => '[gallery id="123" size="medium"]',
'default' => '',
]
);
$this->end_controls_section();
}
/**
* Render shortcode widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$shortcode = $this->get_settings_for_display( 'shortcode' );
$shortcode = do_shortcode( shortcode_unautop( $shortcode ) );
?>
<div class="elementor-shortcode"><?php echo $shortcode; ?></div>
<?php
}
/**
* Render shortcode widget as plain content.
*
* Override the default behavior by printing the shortcode instead of rendering it.
*
* @since 1.0.0
* @access public
*/
public function render_plain_content() {
// In plain mode, render without shortcode
echo $this->get_settings( 'shortcode' );
}
/**
* Render shortcode widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {}
}

View File

@@ -0,0 +1,153 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor sidebar widget.
*
* Elementor widget that insert any sidebar into the page.
*
* @since 1.0.0
*/
class Widget_Sidebar extends Widget_Base {
/**
* Get widget name.
*
* Retrieve sidebar widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'sidebar';
}
/**
* Get widget title.
*
* Retrieve sidebar widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Sidebar', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve sidebar widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-sidebar';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'sidebar', 'widget' ];
}
/**
* Register sidebar widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
global $wp_registered_sidebars;
$options = [];
if ( ! $wp_registered_sidebars ) {
$options[''] = __( 'No sidebars were found', 'elementor' );
} else {
$options[''] = __( 'Choose Sidebar', 'elementor' );
foreach ( $wp_registered_sidebars as $sidebar_id => $sidebar ) {
$options[ $sidebar_id ] = $sidebar['name'];
}
}
$default_key = array_keys( $options );
$default_key = array_shift( $default_key );
$this->start_controls_section(
'section_sidebar',
[
'label' => __( 'Sidebar', 'elementor' ),
]
);
$this->add_control( 'sidebar', [
'label' => __( 'Choose Sidebar', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => $default_key,
'options' => $options,
] );
$this->end_controls_section();
}
/**
* Render sidebar widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$sidebar = $this->get_settings_for_display( 'sidebar' );
if ( empty( $sidebar ) ) {
return;
}
dynamic_sidebar( $sidebar );
}
/**
* Render sidebar widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {}
/**
* Render sidebar widget as plain content.
*
* Override the default render behavior, don't render sidebar content.
*
* @since 1.0.0
* @access public
*/
public function render_plain_content() {}
}

View File

@@ -0,0 +1,663 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor social icons widget.
*
* Elementor widget that displays icons to social pages like Facebook and Twitter.
*
* @since 1.0.0
*/
class Widget_Social_Icons extends Widget_Base {
/**
* Get widget name.
*
* Retrieve social icons widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'social-icons';
}
/**
* Get widget title.
*
* Retrieve social icons widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Social Icons', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve social icons widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-social-icons';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'social', 'icon', 'link' ];
}
/**
* Register social icons widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_social_icon',
[
'label' => __( 'Social Icons', 'elementor' ),
]
);
$repeater = new Repeater();
$repeater->add_control(
'social_icon',
[
'label' => __( 'Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'fa4compatibility' => 'social',
'default' => [
'value' => 'fab fa-wordpress',
'library' => 'fa-brands',
],
'recommended' => [
'fa-brands' => [
'android',
'apple',
'behance',
'bitbucket',
'codepen',
'delicious',
'deviantart',
'digg',
'dribbble',
'elementor',
'facebook',
'flickr',
'foursquare',
'free-code-camp',
'github',
'gitlab',
'globe',
'houzz',
'instagram',
'jsfiddle',
'linkedin',
'medium',
'meetup',
'mix',
'mixcloud',
'odnoklassniki',
'pinterest',
'product-hunt',
'reddit',
'shopping-cart',
'skype',
'slideshare',
'snapchat',
'soundcloud',
'spotify',
'stack-overflow',
'steam',
'telegram',
'thumb-tack',
'tripadvisor',
'tumblr',
'twitch',
'twitter',
'viber',
'vimeo',
'vk',
'weibo',
'weixin',
'whatsapp',
'wordpress',
'xing',
'yelp',
'youtube',
'500px',
],
'fa-solid' => [
'envelope',
'link',
'rss',
],
],
]
);
$repeater->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'default' => [
'is_external' => 'true',
],
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'https://your-link.com', 'elementor' ),
]
);
$repeater->add_control(
'item_icon_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'default',
'options' => [
'default' => __( 'Official Color', 'elementor' ),
'custom' => __( 'Custom', 'elementor' ),
],
]
);
$repeater->add_control(
'item_icon_primary_color',
[
'label' => __( 'Primary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'condition' => [
'item_icon_color' => 'custom',
],
'selectors' => [
'{{WRAPPER}} {{CURRENT_ITEM}}.elementor-social-icon' => 'background-color: {{VALUE}};',
],
]
);
$repeater->add_control(
'item_icon_secondary_color',
[
'label' => __( 'Secondary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'condition' => [
'item_icon_color' => 'custom',
],
'selectors' => [
'{{WRAPPER}} {{CURRENT_ITEM}}.elementor-social-icon i' => 'color: {{VALUE}};',
'{{WRAPPER}} {{CURRENT_ITEM}}.elementor-social-icon svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_control(
'social_icon_list',
[
'label' => __( 'Social Icons', 'elementor' ),
'type' => Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'default' => [
[
'social_icon' => [
'value' => 'fab fa-facebook',
'library' => 'fa-brands',
],
],
[
'social_icon' => [
'value' => 'fab fa-twitter',
'library' => 'fa-brands',
],
],
[
'social_icon' => [
'value' => 'fab fa-youtube',
'library' => 'fa-brands',
],
],
],
'title_field' => '<# var migrated = "undefined" !== typeof __fa4_migrated, social = ( "undefined" === typeof social ) ? false : social; #>{{{ elementor.helpers.getSocialNetworkNameFromIcon( social_icon, social, true, migrated, true ) }}}',
]
);
$this->add_control(
'shape',
[
'label' => __( 'Shape', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'rounded',
'options' => [
'rounded' => __( 'Rounded', 'elementor' ),
'square' => __( 'Square', 'elementor' ),
'circle' => __( 'Circle', 'elementor' ),
],
'prefix_class' => 'elementor-shape-',
]
);
$this->add_responsive_control(
'columns',
[
'label' => __( 'Columns', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => '0',
'options' => [
'0' => __( 'Auto', 'elementor' ),
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
],
'prefix_class' => 'elementor-grid%s-',
'selectors' => [
'{{WRAPPER}}' => '--grid-template-columns: repeat({{VALUE}}, auto);',
],
]
);
$start = is_rtl() ? 'end' : 'start';
$end = is_rtl() ? 'start' : 'end';
$this->add_responsive_control(
'align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
],
'prefix_class' => 'e-grid-align-',
'default' => 'center',
'selectors' => [
'{{WRAPPER}} .elementor-widget-container' => 'text-align: {{VALUE}}',
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_social_style',
[
'label' => __( 'Icon', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'icon_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'default',
'options' => [
'default' => __( 'Official Color', 'elementor' ),
'custom' => __( 'Custom', 'elementor' ),
],
]
);
$this->add_control(
'icon_primary_color',
[
'label' => __( 'Primary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'condition' => [
'icon_color' => 'custom',
],
'selectors' => [
'{{WRAPPER}} .elementor-social-icon' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'icon_secondary_color',
[
'label' => __( 'Secondary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'condition' => [
'icon_color' => 'custom',
],
'selectors' => [
'{{WRAPPER}} .elementor-social-icon i' => 'color: {{VALUE}};',
'{{WRAPPER}} .elementor-social-icon svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'icon_size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 6,
'max' => 300,
],
],
'selectors' => [
'{{WRAPPER}}' => '--icon-size: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_responsive_control(
'icon_padding',
[
'label' => __( 'Padding', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'selectors' => [
'{{WRAPPER}} .elementor-social-icon' => '--icon-padding: {{SIZE}}{{UNIT}}',
],
'default' => [
'unit' => 'em',
],
'tablet_default' => [
'unit' => 'em',
],
'mobile_default' => [
'unit' => 'em',
],
'range' => [
'em' => [
'min' => 0,
'max' => 5,
],
],
]
);
$this->add_responsive_control(
'icon_spacing',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'size' => 5,
],
'selectors' => [
'{{WRAPPER}}' => '--grid-column-gap: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_responsive_control(
'row_gap',
[
'label' => __( 'Rows Gap', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 0,
],
'selectors' => [
'{{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'image_border', // We know this mistake - TODO: 'icon_border' (for hover control condition also)
'selector' => '{{WRAPPER}} .elementor-social-icon',
'separator' => 'before',
]
);
$this->add_control(
'border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_social_hover',
[
'label' => __( 'Icon Hover', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'hover_primary_color',
[
'label' => __( 'Primary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'condition' => [
'icon_color' => 'custom',
],
'selectors' => [
'{{WRAPPER}} .elementor-social-icon:hover' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'hover_secondary_color',
[
'label' => __( 'Secondary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'condition' => [
'icon_color' => 'custom',
],
'selectors' => [
'{{WRAPPER}} .elementor-social-icon:hover i' => 'color: {{VALUE}};',
'{{WRAPPER}} .elementor-social-icon:hover svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_control(
'hover_border_color',
[
'label' => __( 'Border Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'condition' => [
'image_border_border!' => '',
],
'selectors' => [
'{{WRAPPER}} .elementor-social-icon:hover' => 'border-color: {{VALUE}};',
],
]
);
$this->add_control(
'hover_animation',
[
'label' => __( 'Hover Animation', 'elementor' ),
'type' => Controls_Manager::HOVER_ANIMATION,
]
);
$this->end_controls_section();
}
/**
* Render social icons widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$fallback_defaults = [
'fa fa-facebook',
'fa fa-twitter',
'fa fa-google-plus',
];
$class_animation = '';
if ( ! empty( $settings['hover_animation'] ) ) {
$class_animation = ' elementor-animation-' . $settings['hover_animation'];
}
$migration_allowed = Icons_Manager::is_migration_allowed();
?>
<div class="elementor-social-icons-wrapper elementor-grid">
<?php
foreach ( $settings['social_icon_list'] as $index => $item ) {
$migrated = isset( $item['__fa4_migrated']['social_icon'] );
$is_new = empty( $item['social'] ) && $migration_allowed;
$social = '';
// add old default
if ( empty( $item['social'] ) && ! $migration_allowed ) {
$item['social'] = isset( $fallback_defaults[ $index ] ) ? $fallback_defaults[ $index ] : 'fa fa-wordpress';
}
if ( ! empty( $item['social'] ) ) {
$social = str_replace( 'fa fa-', '', $item['social'] );
}
if ( ( $is_new || $migrated ) && 'svg' !== $item['social_icon']['library'] ) {
$social = explode( ' ', $item['social_icon']['value'], 2 );
if ( empty( $social[1] ) ) {
$social = '';
} else {
$social = str_replace( 'fa-', '', $social[1] );
}
}
if ( 'svg' === $item['social_icon']['library'] ) {
$social = get_post_meta( $item['social_icon']['value']['id'], '_wp_attachment_image_alt', true );
}
$link_key = 'link_' . $index;
$this->add_render_attribute( $link_key, 'class', [
'elementor-icon',
'elementor-social-icon',
'elementor-social-icon-' . $social . $class_animation,
'elementor-repeater-item-' . $item['_id'],
] );
$this->add_link_attributes( $link_key, $item['link'] );
?>
<div class="elementor-grid-item">
<a <?php echo $this->get_render_attribute_string( $link_key ); ?>>
<span class="elementor-screen-only"><?php echo ucwords( $social ); ?></span>
<?php
if ( $is_new || $migrated ) {
Icons_Manager::render_icon( $item['social_icon'] );
} else { ?>
<i class="<?php echo esc_attr( $item['social'] ); ?>"></i>
<?php } ?>
</a>
</div>
<?php } ?>
</div>
<?php
}
/**
* Render social icons widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<# var iconsHTML = {}; #>
<div class="elementor-social-icons-wrapper elementor-grid">
<# _.each( settings.social_icon_list, function( item, index ) {
var link = item.link ? item.link.url : '',
migrated = elementor.helpers.isIconMigrated( item, 'social_icon' );
social = elementor.helpers.getSocialNetworkNameFromIcon( item.social_icon, item.social, false, migrated );
#>
<div class="elementor-grid-item">
<a class="elementor-icon elementor-social-icon elementor-social-icon-{{ social }} elementor-animation-{{ settings.hover_animation }} elementor-repeater-item-{{item._id}}" href="{{ link }}">
<span class="elementor-screen-only">{{{ social }}}</span>
<#
iconsHTML[ index ] = elementor.helpers.renderIcon( view, item.social_icon, {}, 'i', 'object' );
if ( ( ! item.social || migrated ) && iconsHTML[ index ] && iconsHTML[ index ].rendered ) { #>
{{{ iconsHTML[ index ].value }}}
<# } else { #>
<i class="{{ item.social }}"></i>
<# }
#>
</a>
</div>
<# } ); #>
</div>
<?php
}
}

View File

@@ -0,0 +1,173 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor spacer widget.
*
* Elementor widget that inserts a space that divides various elements.
*
* @since 1.0.0
*/
class Widget_Spacer extends Widget_Base {
/**
* Get widget name.
*
* Retrieve spacer widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'spacer';
}
/**
* Get widget title.
*
* Retrieve spacer widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Spacer', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve spacer widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-spacer';
}
/**
* Get widget categories.
*
* Retrieve the list of categories the spacer widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* @since 1.0.0
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'basic' ];
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'space' ];
}
/**
* Register spacer widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_spacer',
[
'label' => __( 'Spacer', 'elementor' ),
]
);
$this->add_responsive_control(
'space',
[
'label' => __( 'Space', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 50,
],
'size_units' => [ 'px', 'vh', 'em' ],
'range' => [
'px' => [
'min' => 10,
'max' => 600,
],
'em' => [
'min' => 0.1,
'max' => 20,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-spacer-inner' => 'height: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
}
/**
* Render spacer widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
?>
<div class="elementor-spacer">
<div class="elementor-spacer-inner"></div>
</div>
<?php
}
/**
* Render spacer widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<div class="elementor-spacer">
<div class="elementor-spacer-inner"></div>
</div>
<?php
}
}

View File

@@ -0,0 +1,483 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor star rating widget.
*
* Elementor widget that displays star rating.
*
* @since 2.3.0
*/
class Widget_Star_Rating extends Widget_Base {
/**
* Get widget name.
*
* Retrieve star rating widget name.
*
* @since 2.3.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'star-rating';
}
/**
* Get widget title.
*
* Retrieve star rating widget title.
*
* @since 2.3.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Star Rating', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve star rating widget icon.
*
* @since 2.3.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-rating';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.3.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'star', 'rating', 'rate', 'review' ];
}
/**
* Register star rating widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_rating',
[
'label' => __( 'Rating', 'elementor' ),
]
);
$this->add_control(
'rating_scale',
[
'label' => __( 'Rating Scale', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'5' => '0-5',
'10' => '0-10',
],
'default' => '5',
]
);
$this->add_control(
'rating',
[
'label' => __( 'Rating', 'elementor' ),
'type' => Controls_Manager::NUMBER,
'min' => 0,
'max' => 10,
'step' => 0.1,
'default' => 5,
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'star_style',
[
'label' => __( 'Icon', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'star_fontawesome' => 'Font Awesome',
'star_unicode' => 'Unicode',
],
'default' => 'star_fontawesome',
'render_type' => 'template',
'prefix_class' => 'elementor--star-style-',
'separator' => 'before',
]
);
$this->add_control(
'unmarked_star_style',
[
'label' => __( 'Unmarked Style', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'solid' => [
'title' => __( 'Solid', 'elementor' ),
'icon' => 'eicon-star',
],
'outline' => [
'title' => __( 'Outline', 'elementor' ),
'icon' => 'eicon-star-o',
],
],
'default' => 'solid',
]
);
$this->add_control(
'title',
[
'label' => __( 'Title', 'elementor' ),
'type' => Controls_Manager::TEXT,
'separator' => 'before',
'dynamic' => [
'active' => true,
],
]
);
$this->add_responsive_control(
'align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
],
],
'prefix_class' => 'elementor-star-rating%s--align-',
'selectors' => [
'{{WRAPPER}}' => 'text-align: {{VALUE}}',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_title_style',
[
'label' => __( 'Title', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'title!' => '',
],
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
'selectors' => [
'{{WRAPPER}} .elementor-star-rating__title' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'selector' => '{{WRAPPER}} .elementor-star-rating__title',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'title_shadow',
'selector' => '{{WRAPPER}} .elementor-star-rating__title',
]
);
$this->add_responsive_control(
'title_gap',
[
'label' => __( 'Gap', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 50,
],
],
'selectors' => [
'body:not(.rtl) {{WRAPPER}}:not(.elementor-star-rating--align-justify) .elementor-star-rating__title' => 'margin-right: {{SIZE}}{{UNIT}}',
'body.rtl {{WRAPPER}}:not(.elementor-star-rating--align-justify) .elementor-star-rating__title' => 'margin-left: {{SIZE}}{{UNIT}}',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_stars_style',
[
'label' => __( 'Stars', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'icon_size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-star-rating' => 'font-size: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_responsive_control(
'icon_space',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 50,
],
],
'selectors' => [
'body:not(.rtl) {{WRAPPER}} .elementor-star-rating i:not(:last-of-type)' => 'margin-right: {{SIZE}}{{UNIT}}',
'body.rtl {{WRAPPER}} .elementor-star-rating i:not(:last-of-type)' => 'margin-left: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'stars_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-star-rating i:before' => 'color: {{VALUE}}',
],
'separator' => 'before',
]
);
$this->add_control(
'stars_unmarked_color',
[
'label' => __( 'Unmarked Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-star-rating i' => 'color: {{VALUE}}',
],
]
);
$this->end_controls_section();
}
/**
* @since 2.3.0
* @access protected
*/
protected function get_rating() {
$settings = $this->get_settings_for_display();
$rating_scale = (int) $settings['rating_scale'];
$rating = (float) $settings['rating'] > $rating_scale ? $rating_scale : $settings['rating'];
return [ $rating, $rating_scale ];
}
/**
* Print the actual stars and calculate their filling.
*
* Rating type is float to allow stars-count to be a fraction.
* Floored-rating type is int, to represent the rounded-down stars count.
* In the `for` loop, the index type is float to allow comparing with the rating value.
*
* @since 2.3.0
* @access protected
*/
protected function render_stars( $icon ) {
$rating_data = $this->get_rating();
$rating = (float) $rating_data[0];
$floored_rating = floor( $rating );
$stars_html = '';
for ( $stars = 1.0; $stars <= $rating_data[1]; $stars++ ) {
if ( $stars <= $floored_rating ) {
$stars_html .= '<i class="elementor-star-full">' . $icon . '</i>';
} elseif ( $floored_rating + 1 === $stars && $rating !== $floored_rating ) {
$stars_html .= '<i class="elementor-star-' . ( $rating - $floored_rating ) * 10 . '">' . $icon . '</i>';
} else {
$stars_html .= '<i class="elementor-star-empty">' . $icon . '</i>';
}
}
return $stars_html;
}
/**
* @since 2.3.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$rating_data = $this->get_rating();
$textual_rating = $rating_data[0] . '/' . $rating_data[1];
$icon = '&#xE934;';
if ( 'star_fontawesome' === $settings['star_style'] ) {
if ( 'outline' === $settings['unmarked_star_style'] ) {
$icon = '&#xE933;';
}
} elseif ( 'star_unicode' === $settings['star_style'] ) {
$icon = '&#9733;';
if ( 'outline' === $settings['unmarked_star_style'] ) {
$icon = '&#9734;';
}
}
$this->add_render_attribute( 'icon_wrapper', [
'class' => 'elementor-star-rating',
'title' => $textual_rating,
'itemtype' => 'http://schema.org/Rating',
'itemscope' => '',
'itemprop' => 'reviewRating',
] );
$schema_rating = '<span itemprop="ratingValue" class="elementor-screen-only">' . $textual_rating . '</span>';
$stars_element = '<div ' . $this->get_render_attribute_string( 'icon_wrapper' ) . '>' . $this->render_stars( $icon ) . ' ' . $schema_rating . '</div>';
?>
<div class="elementor-star-rating__wrapper">
<?php if ( ! Utils::is_empty( $settings['title'] ) ) : ?>
<div class="elementor-star-rating__title"><?php echo $settings['title']; ?></div>
<?php endif; ?>
<?php echo $stars_element; ?>
</div>
<?php
}
/**
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<#
var getRating = function() {
var ratingScale = parseInt( settings.rating_scale, 10 ),
rating = settings.rating > ratingScale ? ratingScale : settings.rating;
return [ rating, ratingScale ];
},
ratingData = getRating(),
rating = ratingData[0],
textualRating = ratingData[0] + '/' + ratingData[1],
renderStars = function( icon ) {
var starsHtml = '',
flooredRating = Math.floor( rating );
for ( var stars = 1; stars <= ratingData[1]; stars++ ) {
if ( stars <= flooredRating ) {
starsHtml += '<i class="elementor-star-full">' + icon + '</i>';
} else if ( flooredRating + 1 === stars && rating !== flooredRating ) {
starsHtml += '<i class="elementor-star-' + ( rating - flooredRating ).toFixed( 1 ) * 10 + '">' + icon + '</i>';
} else {
starsHtml += '<i class="elementor-star-empty">' + icon + '</i>';
}
}
return starsHtml;
},
icon = '&#xE934;';
if ( 'star_fontawesome' === settings.star_style ) {
if ( 'outline' === settings.unmarked_star_style ) {
icon = '&#xE933;';
}
} else if ( 'star_unicode' === settings.star_style ) {
icon = '&#9733;';
if ( 'outline' === settings.unmarked_star_style ) {
icon = '&#9734;';
}
}
view.addRenderAttribute( 'iconWrapper', 'class', 'elementor-star-rating' );
view.addRenderAttribute( 'iconWrapper', 'itemtype', 'http://schema.org/Rating' );
view.addRenderAttribute( 'iconWrapper', 'title', textualRating );
view.addRenderAttribute( 'iconWrapper', 'itemscope', '' );
view.addRenderAttribute( 'iconWrapper', 'itemprop', 'reviewRating' );
var stars = renderStars( icon );
#>
<div class="elementor-star-rating__wrapper">
<# if ( ! _.isEmpty( settings.title ) ) { #>
<div class="elementor-star-rating__title">{{ settings.title }}</div>
<# } #>
<div {{{ view.getRenderAttributeString( 'iconWrapper' ) }}} >
{{{ stars }}}
<span itemprop="ratingValue" class="elementor-screen-only">{{ textualRating }}</span>
</div>
</div>
<?php
}
}

View File

@@ -0,0 +1,563 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor tabs widget.
*
* Elementor widget that displays vertical or horizontal tabs with different
* pieces of content.
*
* @since 1.0.0
*/
class Widget_Tabs extends Widget_Base {
/**
* Get widget name.
*
* Retrieve tabs widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'tabs';
}
/**
* Get widget title.
*
* Retrieve tabs widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Tabs', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve tabs widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-tabs';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'tabs', 'accordion', 'toggle' ];
}
/**
* Register tabs widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_tabs',
[
'label' => __( 'Tabs', 'elementor' ),
]
);
$repeater = new Repeater();
$repeater->add_control(
'tab_title',
[
'label' => __( 'Title & Description', 'elementor' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Tab Title', 'elementor' ),
'placeholder' => __( 'Tab Title', 'elementor' ),
'label_block' => true,
'dynamic' => [
'active' => true,
],
]
);
$repeater->add_control(
'tab_content',
[
'label' => __( 'Content', 'elementor' ),
'default' => __( 'Tab Content', 'elementor' ),
'placeholder' => __( 'Tab Content', 'elementor' ),
'type' => Controls_Manager::WYSIWYG,
'show_label' => false,
]
);
$this->add_control(
'tabs',
[
'label' => __( 'Tabs Items', 'elementor' ),
'type' => Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'default' => [
[
'tab_title' => __( 'Tab #1', 'elementor' ),
'tab_content' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
],
[
'tab_title' => __( 'Tab #2', 'elementor' ),
'tab_content' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
],
],
'title_field' => '{{{ tab_title }}}',
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->add_control(
'type',
[
'label' => __( 'Position', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'horizontal',
'options' => [
'horizontal' => __( 'Horizontal', 'elementor' ),
'vertical' => __( 'Vertical', 'elementor' ),
],
'prefix_class' => 'elementor-tabs-view-',
'separator' => 'before',
]
);
$this->add_control(
'tabs_align_horizontal',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'' => [
'title' => __( 'Start', 'elementor' ),
'icon' => 'eicon-h-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-h-align-center',
],
'end' => [
'title' => __( 'End', 'elementor' ),
'icon' => 'eicon-h-align-right',
],
'stretch' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-h-align-stretch',
],
],
'prefix_class' => 'elementor-tabs-alignment-',
'condition' => [
'type' => 'horizontal',
],
]
);
$this->add_control(
'tabs_align_vertical',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'' => [
'title' => __( 'Start', 'elementor' ),
'icon' => 'eicon-v-align-top',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-v-align-middle',
],
'end' => [
'title' => __( 'End', 'elementor' ),
'icon' => 'eicon-v-align-bottom',
],
'stretch' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-v-align-stretch',
],
],
'prefix_class' => 'elementor-tabs-alignment-',
'condition' => [
'type' => 'vertical',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_tabs_style',
[
'label' => __( 'Tabs', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'navigation_width',
[
'label' => __( 'Navigation Width', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'unit' => '%',
],
'range' => [
'%' => [
'min' => 10,
'max' => 50,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-tabs-wrapper' => 'width: {{SIZE}}{{UNIT}}',
],
'condition' => [
'type' => 'vertical',
],
]
);
$this->add_control(
'border_width',
[
'label' => __( 'Border Width', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 1,
],
'range' => [
'px' => [
'min' => 0,
'max' => 10,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-tab-title, {{WRAPPER}} .elementor-tab-title:before, {{WRAPPER}} .elementor-tab-title:after, {{WRAPPER}} .elementor-tab-content, {{WRAPPER}} .elementor-tabs-content-wrapper' => 'border-width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'border_color',
[
'label' => __( 'Border Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-mobile-title, {{WRAPPER}} .elementor-tab-desktop-title.elementor-active, {{WRAPPER}} .elementor-tab-title:before, {{WRAPPER}} .elementor-tab-title:after, {{WRAPPER}} .elementor-tab-content, {{WRAPPER}} .elementor-tabs-content-wrapper' => 'border-color: {{VALUE}};',
],
]
);
$this->add_control(
'background_color',
[
'label' => __( 'Background Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-desktop-title.elementor-active' => 'background-color: {{VALUE}};',
'{{WRAPPER}} .elementor-tabs-content-wrapper' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'heading_title',
[
'label' => __( 'Title', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'tab_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-title, {{WRAPPER}} .elementor-tab-title a' => 'color: {{VALUE}}',
],
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
]
);
$this->add_control(
'tab_active_color',
[
'label' => __( 'Active Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-title.elementor-active,
{{WRAPPER}} .elementor-tab-title.elementor-active a' => 'color: {{VALUE}}',
],
'global' => [
'default' => Global_Colors::COLOR_ACCENT,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'tab_typography',
'selector' => '{{WRAPPER}} .elementor-tab-title',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'title_shadow',
'selector' => '{{WRAPPER}} .elementor-tab-title',
]
);
$this->add_control(
'title_align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}} .elementor-tab-title' => 'text-align: {{VALUE}};',
],
'condition' => [
'tabs_align' => 'stretch',
],
]
);
$this->add_control(
'heading_content',
[
'label' => __( 'Content', 'elementor' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'content_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-content' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'content_typography',
'selector' => '{{WRAPPER}} .elementor-tab-content',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'content_shadow',
'selector' => '{{WRAPPER}} .elementor-tab-content',
]
);
$this->end_controls_section();
}
/**
* Render tabs widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$tabs = $this->get_settings_for_display( 'tabs' );
$id_int = substr( $this->get_id_int(), 0, 3 );
$a11y_improvements_experiment = Plugin::$instance->experiments->is_feature_active( 'a11y_improvements' );
$this->add_render_attribute( 'elementor-tabs', 'class', 'elementor-tabs' );
?>
<div <?php echo $this->get_render_attribute_string( 'elementor-tabs' ); ?>>
<div class="elementor-tabs-wrapper" role="tablist" >
<?php
foreach ( $tabs as $index => $item ) :
$tab_count = $index + 1;
$tab_title_setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $index );
$tab_title = $a11y_improvements_experiment ? $item['tab_title'] : '<a href="">' . $item['tab_title'] . '</a>';
$this->add_render_attribute( $tab_title_setting_key, [
'id' => 'elementor-tab-title-' . $id_int . $tab_count,
'class' => [ 'elementor-tab-title', 'elementor-tab-desktop-title' ],
'aria-selected' => 1 === $tab_count ? 'true' : 'false',
'data-tab' => $tab_count,
'role' => 'tab',
'tabindex' => 1 === $tab_count ? '0' : '-1',
'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
'aria-expanded' => 'false',
] );
?>
<div <?php echo $this->get_render_attribute_string( $tab_title_setting_key ); ?>><?php echo $tab_title; ?></div>
<?php endforeach; ?>
</div>
<div class="elementor-tabs-content-wrapper" role="tablist" aria-orientation="vertical">
<?php
foreach ( $tabs as $index => $item ) :
$tab_count = $index + 1;
$hidden = 1 === $tab_count ? 'false' : 'hidden';
$tab_content_setting_key = $this->get_repeater_setting_key( 'tab_content', 'tabs', $index );
$tab_title_mobile_setting_key = $this->get_repeater_setting_key( 'tab_title_mobile', 'tabs', $tab_count );
$this->add_render_attribute( $tab_content_setting_key, [
'id' => 'elementor-tab-content-' . $id_int . $tab_count,
'class' => [ 'elementor-tab-content', 'elementor-clearfix' ],
'data-tab' => $tab_count,
'role' => 'tabpanel',
'aria-labelledby' => 'elementor-tab-title-' . $id_int . $tab_count,
'tabindex' => '0',
'hidden' => $hidden,
] );
$this->add_render_attribute( $tab_title_mobile_setting_key, [
'class' => [ 'elementor-tab-title', 'elementor-tab-mobile-title' ],
'aria-selected' => 1 === $tab_count ? 'true' : 'false',
'data-tab' => $tab_count,
'role' => 'tab',
'tabindex' => 1 === $tab_count ? '0' : '-1',
'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
'aria-expanded' => 'false',
] );
$this->add_inline_editing_attributes( $tab_content_setting_key, 'advanced' );
?>
<div <?php echo $this->get_render_attribute_string( $tab_title_mobile_setting_key ); ?>><?php echo $item['tab_title']; ?></div>
<div <?php echo $this->get_render_attribute_string( $tab_content_setting_key ); ?>><?php echo $this->parse_text_editor( $item['tab_content'] ); ?></div>
<?php endforeach; ?>
</div>
</div>
<?php
}
/**
* Render tabs widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<div class="elementor-tabs" role="tablist" aria-orientation="vertical">
<# if ( settings.tabs ) {
var elementUid = view.getIDInt().toString().substr( 0, 3 ); #>
<div class="elementor-tabs-wrapper" role="tablist">
<# _.each( settings.tabs, function( item, index ) {
var tabCount = index + 1,
tabUid = elementUid + tabCount,
tabTitleKey = 'tab-title-' + tabUid;
view.addRenderAttribute( tabTitleKey, {
'id': 'elementor-tab-title-' + tabUid,
'class': [ 'elementor-tab-title','elementor-tab-desktop-title' ],
'data-tab': tabCount,
'role': 'tab',
'tabindex': 1 === tabCount ? '0' : '-1',
'aria-controls': 'elementor-tab-content-' + tabUid,
'aria-expanded': 'false',
} );
#>
<div {{{ view.getRenderAttributeString( tabTitleKey ) }}}>{{{ item.tab_title }}}</div>
<# } ); #>
</div>
<div class="elementor-tabs-content-wrapper">
<# _.each( settings.tabs, function( item, index ) {
var tabCount = index + 1,
tabContentKey = view.getRepeaterSettingKey( 'tab_content', 'tabs',index );
view.addRenderAttribute( tabContentKey, {
'id': 'elementor-tab-content-' + elementUid + tabCount,
'class': [ 'elementor-tab-content', 'elementor-clearfix', 'elementor-repeater-item-' + item._id ],
'data-tab': tabCount,
'role' : 'tabpanel',
'aria-labelledby' : 'elementor-tab-title-' + elementUid + tabCount
} );
view.addInlineEditingAttributes( tabContentKey, 'advanced' ); #>
<div class="elementor-tab-title elementor-tab-mobile-title" data-tab="{{ tabCount }}" role="tab">{{{ item.tab_title }}}</div>
<div {{{ view.getRenderAttributeString( tabContentKey ) }}}>{{{ item.tab_content }}}</div>
<# } ); #>
</div>
<# } #>
</div>
<?php
}
}

View File

@@ -0,0 +1,608 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor testimonial widget.
*
* Elementor widget that displays customer testimonials that show social proof.
*
* @since 1.0.0
*/
class Widget_Testimonial extends Widget_Base {
/**
* Get widget name.
*
* Retrieve testimonial widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'testimonial';
}
/**
* Get widget title.
*
* Retrieve testimonial widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Testimonial', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve testimonial widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-testimonial';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'testimonial', 'blockquote' ];
}
/**
* Register testimonial widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_testimonial',
[
'label' => __( 'Testimonial', 'elementor' ),
]
);
$this->add_control(
'testimonial_content',
[
'label' => __( 'Content', 'elementor' ),
'type' => Controls_Manager::TEXTAREA,
'dynamic' => [
'active' => true,
],
'rows' => '10',
'default' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
]
);
$this->add_control(
'testimonial_image',
[
'label' => __( 'Choose Image', 'elementor' ),
'type' => Controls_Manager::MEDIA,
'dynamic' => [
'active' => true,
],
'default' => [
'url' => Utils::get_placeholder_image_src(),
],
]
);
$this->add_group_control(
Group_Control_Image_Size::get_type(),
[
'name' => 'testimonial_image', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `testimonial_image_size` and `testimonial_image_custom_dimension`.
'default' => 'full',
'separator' => 'none',
]
);
$this->add_control(
'testimonial_name',
[
'label' => __( 'Name', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => 'John Doe',
]
);
$this->add_control(
'testimonial_job',
[
'label' => __( 'Title', 'elementor' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => 'Designer',
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'dynamic' => [
'active' => true,
],
'placeholder' => __( 'https://your-link.com', 'elementor' ),
]
);
$this->add_control(
'testimonial_image_position',
[
'label' => __( 'Image Position', 'elementor' ),
'type' => Controls_Manager::SELECT,
'default' => 'aside',
'options' => [
'aside' => __( 'Aside', 'elementor' ),
'top' => __( 'Top', 'elementor' ),
],
'condition' => [
'testimonial_image[url]!' => '',
],
'separator' => 'before',
'style_transfer' => true,
]
);
$this->add_control(
'testimonial_alignment',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'default' => 'center',
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
],
'style_transfer' => true,
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->end_controls_section();
// Content.
$this->start_controls_section(
'section_style_testimonial_content',
[
'label' => __( 'Content', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'content_content_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-testimonial-content' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'content_typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
'selector' => '{{WRAPPER}} .elementor-testimonial-content',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'content_shadow',
'selector' => '{{WRAPPER}} .elementor-testimonial-content',
]
);
$this->end_controls_section();
// Image.
$this->start_controls_section(
'section_style_testimonial_image',
[
'label' => __( 'Image', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'testimonial_image[url]!' => '',
],
]
);
$this->add_control(
'image_size',
[
'label' => __( 'Image Size', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'range' => [
'px' => [
'min' => 20,
'max' => 200,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-testimonial-wrapper .elementor-testimonial-image img' => 'width: {{SIZE}}{{UNIT}};height: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'image_border',
'selector' => '{{WRAPPER}} .elementor-testimonial-wrapper .elementor-testimonial-image img',
'separator' => 'before',
]
);
$this->add_control(
'image_border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-testimonial-wrapper .elementor-testimonial-image img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
// Name.
$this->start_controls_section(
'section_style_testimonial_name',
[
'label' => __( 'Name', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'name_text_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-testimonial-name' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'name_typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
'selector' => '{{WRAPPER}} .elementor-testimonial-name',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'name_shadow',
'selector' => '{{WRAPPER}} .elementor-testimonial-name',
]
);
$this->end_controls_section();
// Job.
$this->start_controls_section(
'section_style_testimonial_job',
[
'label' => __( 'Title', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'job_text_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_SECONDARY,
],
'default' => '',
'selectors' => [
'{{WRAPPER}} .elementor-testimonial-job' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'job_typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_SECONDARY,
],
'selector' => '{{WRAPPER}} .elementor-testimonial-job',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'job_shadow',
'selector' => '{{WRAPPER}} .elementor-testimonial-job',
]
);
$this->end_controls_section();
}
/**
* Render testimonial widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$this->add_render_attribute( 'wrapper', 'class', 'elementor-testimonial-wrapper' );
if ( $settings['testimonial_alignment'] ) {
$this->add_render_attribute( 'wrapper', 'class', 'elementor-testimonial-text-align-' . $settings['testimonial_alignment'] );
}
$this->add_render_attribute( 'meta', 'class', 'elementor-testimonial-meta' );
if ( $settings['testimonial_image']['url'] ) {
$this->add_render_attribute( 'meta', 'class', 'elementor-has-image' );
}
if ( $settings['testimonial_image_position'] ) {
$this->add_render_attribute( 'meta', 'class', 'elementor-testimonial-image-position-' . $settings['testimonial_image_position'] );
}
$has_content = ! ! $settings['testimonial_content'];
$has_image = ! ! $settings['testimonial_image']['url'];
$has_name = ! ! $settings['testimonial_name'];
$has_job = ! ! $settings['testimonial_job'];
if ( ! $has_content && ! $has_image && ! $has_name && ! $has_job ) {
return;
}
if ( ! empty( $settings['link']['url'] ) ) {
$this->add_link_attributes( 'link', $settings['link'] );
}
?>
<div <?php echo $this->get_render_attribute_string( 'wrapper' ); ?>>
<?php
if ( $has_content ) :
$this->add_render_attribute( 'testimonial_content', 'class', 'elementor-testimonial-content' );
$this->add_inline_editing_attributes( 'testimonial_content' );
?>
<div <?php echo $this->get_render_attribute_string( 'testimonial_content' ); ?>><?php echo $settings['testimonial_content']; ?></div>
<?php endif; ?>
<?php if ( $has_image || $has_name || $has_job ) : ?>
<div <?php echo $this->get_render_attribute_string( 'meta' ); ?>>
<div class="elementor-testimonial-meta-inner">
<?php if ( $has_image ) : ?>
<div class="elementor-testimonial-image">
<?php
$image_html = Group_Control_Image_Size::get_attachment_image_html( $settings, 'testimonial_image' );
if ( ! empty( $settings['link']['url'] ) ) :
$image_html = '<a ' . $this->get_render_attribute_string( 'link' ) . '>' . $image_html . '</a>';
endif;
echo $image_html;
?>
</div>
<?php endif; ?>
<?php if ( $has_name || $has_job ) : ?>
<div class="elementor-testimonial-details">
<?php
if ( $has_name ) :
$this->add_render_attribute( 'testimonial_name', 'class', 'elementor-testimonial-name' );
$this->add_inline_editing_attributes( 'testimonial_name', 'none' );
$testimonial_name_html = $settings['testimonial_name'];
if ( ! empty( $settings['link']['url'] ) ) :
?>
<a <?php echo $this->get_render_attribute_string( 'testimonial_name' ) . ' ' . $this->get_render_attribute_string( 'link' ); ?>><?php echo $testimonial_name_html; ?></a>
<?php
else :
?>
<div <?php echo $this->get_render_attribute_string( 'testimonial_name' ); ?>><?php echo $testimonial_name_html; ?></div>
<?php
endif;
endif; ?>
<?php
if ( $has_job ) :
$this->add_render_attribute( 'testimonial_job', 'class', 'elementor-testimonial-job' );
$this->add_inline_editing_attributes( 'testimonial_job', 'none' );
$testimonial_job_html = $settings['testimonial_job'];
if ( ! empty( $settings['link']['url'] ) ) :
?>
<a <?php echo $this->get_render_attribute_string( 'testimonial_job' ) . ' ' . $this->get_render_attribute_string( 'link' ); ?>><?php echo $testimonial_job_html; ?></a>
<?php
else :
?>
<div <?php echo $this->get_render_attribute_string( 'testimonial_job' ); ?>><?php echo $testimonial_job_html; ?></div>
<?php
endif;
endif; ?>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
</div>
<?php
}
/**
* Render testimonial widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<#
var image = {
id: settings.testimonial_image.id,
url: settings.testimonial_image.url,
size: settings.testimonial_image_size,
dimension: settings.testimonial_image_custom_dimension,
model: view.getEditModel()
};
var imageUrl = false, hasImage = '';
if ( '' !== settings.testimonial_image.url ) {
imageUrl = elementor.imagesManager.getImageUrl( image );
hasImage = ' elementor-has-image';
var imageHtml = '<img src="' + imageUrl + '" alt="testimonial" />';
if ( settings.link.url ) {
imageHtml = '<a href="' + settings.link.url + '">' + imageHtml + '</a>';
}
}
var testimonial_alignment = settings.testimonial_alignment ? ' elementor-testimonial-text-align-' + settings.testimonial_alignment : '';
var testimonial_image_position = settings.testimonial_image_position ? ' elementor-testimonial-image-position-' + settings.testimonial_image_position : '';
#>
<div class="elementor-testimonial-wrapper{{ testimonial_alignment }}">
<# if ( '' !== settings.testimonial_content ) {
view.addRenderAttribute( 'testimonial_content', 'class', 'elementor-testimonial-content' );
view.addInlineEditingAttributes( 'testimonial_content' );
#>
<div {{{ view.getRenderAttributeString( 'testimonial_content' ) }}}>{{{ settings.testimonial_content }}}</div>
<# } #>
<div class="elementor-testimonial-meta{{ hasImage }}{{ testimonial_image_position }}">
<div class="elementor-testimonial-meta-inner">
<# if ( imageUrl ) { #>
<div class="elementor-testimonial-image">{{{ imageHtml }}}</div>
<# } #>
<div class="elementor-testimonial-details">
<?php $this->render_testimonial_description(); ?>
</div>
</div>
</div>
</div>
<?php
}
protected function render_testimonial_description() {
?>
<#
if ( '' !== settings.testimonial_name ) {
view.addRenderAttribute( 'testimonial_name', 'class', 'elementor-testimonial-name' );
view.addInlineEditingAttributes( 'testimonial_name', 'none' );
if ( settings.link.url ) {
#>
<a href="{{{ settings.link.url }}}" {{{ view.getRenderAttributeString( 'testimonial_name' ) }}}>{{{ settings.testimonial_name }}}</a>
<#
} else {
#>
<div {{{ view.getRenderAttributeString( 'testimonial_name' ) }}}>{{{ settings.testimonial_name }}}</div>
<#
}
}
if ( '' !== settings.testimonial_job ) {
view.addRenderAttribute( 'testimonial_job', 'class', 'elementor-testimonial-job' );
view.addInlineEditingAttributes( 'testimonial_job', 'none' );
if ( settings.link.url ) {
#>
<a href="{{{ settings.link.url }}}" {{{ view.getRenderAttributeString( 'testimonial_job' ) }}}>{{{ settings.testimonial_job }}}</a>
<#
} else {
#>
<div {{{ view.getRenderAttributeString( 'testimonial_job' ) }}}>{{{ settings.testimonial_job }}}</div>
<#
}
}
#>
<?php
}
}

View File

@@ -0,0 +1,470 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor text editor widget.
*
* Elementor widget that displays a WYSIWYG text editor, just like the WordPress
* editor.
*
* @since 1.0.0
*/
class Widget_Text_Editor extends Widget_Base {
/**
* Get widget name.
*
* Retrieve text editor widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'text-editor';
}
/**
* Get widget title.
*
* Retrieve text editor widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Text Editor', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve text editor widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-text';
}
/**
* Get widget categories.
*
* Retrieve the list of categories the text editor widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* @since 2.0.0
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'basic' ];
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'text', 'editor' ];
}
/**
* Register text editor widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_editor',
[
'label' => __( 'Text Editor', 'elementor' ),
]
);
$this->add_control(
'editor',
[
'label' => '',
'type' => Controls_Manager::WYSIWYG,
'default' => '<p>' . __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ) . '</p>',
]
);
$this->add_control(
'drop_cap', [
'label' => __( 'Drop Cap', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => __( 'Off', 'elementor' ),
'label_on' => __( 'On', 'elementor' ),
'prefix_class' => 'elementor-drop-cap-',
'frontend_available' => true,
]
);
$text_columns = range( 1, 10 );
$text_columns = array_combine( $text_columns, $text_columns );
$text_columns[''] = __( 'Default', 'elementor' );
$this->add_responsive_control(
'text_columns',
[
'label' => __( 'Columns', 'elementor' ),
'type' => Controls_Manager::SELECT,
'separator' => 'before',
'options' => $text_columns,
'selectors' => [
'{{WRAPPER}}' => 'columns: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'column_gap',
[
'label' => __( 'Columns Gap', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'vw' ],
'range' => [
'px' => [
'max' => 100,
],
'%' => [
'max' => 10,
'step' => 0.1,
],
'vw' => [
'max' => 10,
'step' => 0.1,
],
'em' => [
'max' => 10,
'step' => 0.1,
],
],
'selectors' => [
'{{WRAPPER}}' => 'column-gap: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style',
[
'label' => __( 'Text Editor', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => __( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
],
],
'selectors' => [
'{{WRAPPER}}' => 'text-align: {{VALUE}};',
],
]
);
$this->add_control(
'text_color',
[
'label' => __( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '',
'selectors' => [
'{{WRAPPER}}' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'text_shadow',
'selector' => '{{WRAPPER}}',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_drop_cap',
[
'label' => __( 'Drop Cap', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'drop_cap' => 'yes',
],
]
);
$this->add_control(
'drop_cap_view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'default' => __( 'Default', 'elementor' ),
'stacked' => __( 'Stacked', 'elementor' ),
'framed' => __( 'Framed', 'elementor' ),
],
'default' => 'default',
'prefix_class' => 'elementor-drop-cap-view-',
]
);
$this->add_control(
'drop_cap_primary_color',
[
'label' => __( 'Primary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}.elementor-drop-cap-view-stacked .elementor-drop-cap' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-drop-cap-view-framed .elementor-drop-cap, {{WRAPPER}}.elementor-drop-cap-view-default .elementor-drop-cap' => 'color: {{VALUE}}; border-color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
]
);
$this->add_control(
'drop_cap_secondary_color',
[
'label' => __( 'Secondary Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}.elementor-drop-cap-view-framed .elementor-drop-cap' => 'background-color: {{VALUE}};',
'{{WRAPPER}}.elementor-drop-cap-view-stacked .elementor-drop-cap' => 'color: {{VALUE}};',
],
'condition' => [
'drop_cap_view!' => 'default',
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'drop_cap_shadow',
'selector' => '{{WRAPPER}} .elementor-drop-cap',
]
);
$this->add_control(
'drop_cap_size',
[
'label' => __( 'Size', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 5,
],
'range' => [
'px' => [
'max' => 30,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-drop-cap' => 'padding: {{SIZE}}{{UNIT}};',
],
'condition' => [
'drop_cap_view!' => 'default',
],
]
);
$this->add_control(
'drop_cap_space',
[
'label' => __( 'Space', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 10,
],
'range' => [
'px' => [
'max' => 50,
],
],
'selectors' => [
'body:not(.rtl) {{WRAPPER}} .elementor-drop-cap' => 'margin-right: {{SIZE}}{{UNIT}};',
'body.rtl {{WRAPPER}} .elementor-drop-cap' => 'margin-left: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'drop_cap_border_radius',
[
'label' => __( 'Border Radius', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ '%', 'px' ],
'default' => [
'unit' => '%',
],
'range' => [
'%' => [
'max' => 50,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-drop-cap' => 'border-radius: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'drop_cap_border_width', [
'label' => __( 'Border Width', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'selectors' => [
'{{WRAPPER}} .elementor-drop-cap' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'drop_cap_view' => 'framed',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'drop_cap_typography',
'selector' => '{{WRAPPER}} .elementor-drop-cap-letter',
'exclude' => [
'letter_spacing',
],
]
);
$this->end_controls_section();
}
/**
* Render text editor widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$editor_content = $this->get_settings_for_display( 'editor' );
$editor_content = $this->parse_text_editor( $editor_content );
if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) {
$this->add_render_attribute( 'editor', 'class', [ 'elementor-text-editor', 'elementor-clearfix' ] );
}
$this->add_inline_editing_attributes( 'editor', 'advanced' );
?>
<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
<div <?php echo $this->get_render_attribute_string( 'editor' ); ?>>
<?php } ?>
<?php echo $editor_content; ?>
<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
</div>
<?php } ?>
<?php
}
/**
* Render text editor widget as plain content.
*
* Override the default behavior by printing the content without rendering it.
*
* @since 1.0.0
* @access public
*/
public function render_plain_content() {
// In plain mode, render without shortcode
echo $this->get_settings( 'editor' );
}
/**
* Render text editor widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<#
<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
view.addRenderAttribute( 'editor', 'class', [ 'elementor-text-editor', 'elementor-clearfix' ] );
<?php } ?>
view.addInlineEditingAttributes( 'editor', 'advanced' );
#>
<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
<div {{{ view.getRenderAttributeString( 'editor' ) }}}>
<?php } ?>
{{{ settings.editor }}}
<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
</div>
<?php } ?>
<?php
}
}

View File

@@ -0,0 +1,691 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
/**
* Elementor toggle widget.
*
* Elementor widget that displays a collapsible display of content in an toggle
* style, allowing the user to open multiple items.
*
* @since 1.0.0
*/
class Widget_Toggle extends Widget_Base {
/**
* Get widget name.
*
* Retrieve toggle widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'toggle';
}
/**
* Get widget title.
*
* Retrieve toggle widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Toggle', 'elementor' );
}
/**
* Get widget icon.
*
* Retrieve toggle widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-toggle';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'tabs', 'accordion', 'toggle' ];
}
/**
* Register toggle widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_toggle',
[
'label' => __( 'Toggle', 'elementor' ),
]
);
$repeater = new Repeater();
$repeater->add_control(
'tab_title',
[
'label' => __( 'Title & Description', 'elementor' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Toggle Title', 'elementor' ),
'label_block' => true,
'dynamic' => [
'active' => true,
],
]
);
$repeater->add_control(
'tab_content',
[
'label' => __( 'Content', 'elementor' ),
'type' => Controls_Manager::WYSIWYG,
'default' => __( 'Toggle Content', 'elementor' ),
'show_label' => false,
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'tabs',
[
'label' => __( 'Toggle Items', 'elementor' ),
'type' => Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'default' => [
[
'tab_title' => __( 'Toggle #1', 'elementor' ),
'tab_content' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
],
[
'tab_title' => __( 'Toggle #2', 'elementor' ),
'tab_content' => __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
],
],
'title_field' => '{{{ tab_title }}}',
]
);
$this->add_control(
'view',
[
'label' => __( 'View', 'elementor' ),
'type' => Controls_Manager::HIDDEN,
'default' => 'traditional',
]
);
$this->add_control(
'selected_icon',
[
'label' => __( 'Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'separator' => 'before',
'fa4compatibility' => 'icon',
'default' => [
'value' => 'fas fa-caret' . ( is_rtl() ? '-left' : '-right' ),
'library' => 'fa-solid',
],
'recommended' => [
'fa-solid' => [
'chevron-down',
'angle-down',
'angle-double-down',
'caret-down',
'caret-square-down',
],
'fa-regular' => [
'caret-square-down',
],
],
'label_block' => false,
'skin' => 'inline',
]
);
$this->add_control(
'selected_active_icon',
[
'label' => __( 'Active Icon', 'elementor' ),
'type' => Controls_Manager::ICONS,
'fa4compatibility' => 'icon_active',
'default' => [
'value' => 'fas fa-caret-up',
'library' => 'fa-solid',
],
'recommended' => [
'fa-solid' => [
'chevron-up',
'angle-up',
'angle-double-up',
'caret-up',
'caret-square-up',
],
'fa-regular' => [
'caret-square-up',
],
],
'skin' => 'inline',
'label_block' => false,
'condition' => [
'selected_icon[value]!' => '',
],
]
);
$this->add_control(
'title_html_tag',
[
'label' => __( 'Title HTML Tag', 'elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'h1' => 'H1',
'h2' => 'H2',
'h3' => 'H3',
'h4' => 'H4',
'h5' => 'H5',
'h6' => 'H6',
'div' => 'div',
],
'default' => 'div',
'separator' => 'before',
]
);
$this->add_control(
'faq_schema',
[
'label' => __( 'FAQ Schema', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'separator' => 'before',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_toggle_style',
[
'label' => __( 'Toggle', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'border_width',
[
'label' => __( 'Border Width', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 10,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-tab-title' => 'border-width: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .elementor-tab-content' => 'border-width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'border_color',
[
'label' => __( 'Border Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-content' => 'border-bottom-color: {{VALUE}};',
'{{WRAPPER}} .elementor-tab-title' => 'border-color: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'space_between',
[
'label' => __( 'Space Between', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-toggle-item:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'box_shadow',
'selector' => '{{WRAPPER}} .elementor-toggle-item',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_toggle_style_title',
[
'label' => __( 'Title', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'title_background',
[
'label' => __( 'Background', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-title' => 'background-color: {{VALUE}};',
],
]
);
// The title selector specificity is to override Theme Style
$this->add_control(
'title_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-toggle-title, {{WRAPPER}} .elementor-toggle-icon' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
]
);
$this->add_control(
'tab_active_color',
[
'label' => __( 'Active Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-title.elementor-active a, {{WRAPPER}} .elementor-tab-title.elementor-active .elementor-toggle-icon' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_ACCENT,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'selector' => '{{WRAPPER}} .elementor-toggle-title',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'title_shadow',
'selector' => '{{WRAPPER}} .elementor-toggle-title',
]
);
$this->add_responsive_control(
'title_padding',
[
'label' => __( 'Padding', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-tab-title' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_toggle_style_icon',
[
'label' => __( 'Icon', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'selected_icon[value]!' => '',
],
]
);
$this->add_control(
'icon_align',
[
'label' => __( 'Alignment', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Start', 'elementor' ),
'icon' => 'eicon-h-align-left',
],
'right' => [
'title' => __( 'End', 'elementor' ),
'icon' => 'eicon-h-align-right',
],
],
'default' => is_rtl() ? 'right' : 'left',
'toggle' => false,
]
);
$this->add_control(
'icon_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-title .elementor-toggle-icon i:before' => 'color: {{VALUE}};',
'{{WRAPPER}} .elementor-tab-title .elementor-toggle-icon svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_control(
'icon_active_color',
[
'label' => __( 'Active Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-title.elementor-active .elementor-toggle-icon i:before' => 'color: {{VALUE}};',
'{{WRAPPER}} .elementor-tab-title.elementor-active .elementor-toggle-icon svg' => 'fill: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'icon_space',
[
'label' => __( 'Spacing', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-toggle-icon.elementor-toggle-icon-left' => 'margin-right: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .elementor-toggle-icon.elementor-toggle-icon-right' => 'margin-left: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_toggle_style_content',
[
'label' => __( 'Content', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'content_background_color',
[
'label' => __( 'Background', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-content' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'content_color',
[
'label' => __( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-tab-content' => 'color: {{VALUE}};',
],
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'content_typography',
'selector' => '{{WRAPPER}} .elementor-tab-content',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'content_shadow',
'selector' => '{{WRAPPER}} .elementor-tab-content',
]
);
$this->add_responsive_control(
'content_padding',
[
'label' => __( 'Padding', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .elementor-tab-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
}
/**
* Render toggle widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$id_int = substr( $this->get_id_int(), 0, 3 );
$migrated = isset( $settings['__fa4_migrated']['selected_icon'] );
if ( ! isset( $settings['icon'] ) && ! Icons_Manager::is_migration_allowed() ) {
// @todo: remove when deprecated
// added as bc in 2.6
// add old default
$settings['icon'] = 'fa fa-caret' . ( is_rtl() ? '-left' : '-right' );
$settings['icon_active'] = 'fa fa-caret-up';
$settings['icon_align'] = $this->get_settings( 'icon_align' );
}
$is_new = empty( $settings['icon'] ) && Icons_Manager::is_migration_allowed();
$has_icon = ( ! $is_new || ! empty( $settings['selected_icon']['value'] ) );
?>
<div class="elementor-toggle" role="tablist">
<?php
foreach ( $settings['tabs'] as $index => $item ) :
$tab_count = $index + 1;
$tab_title_setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $index );
$tab_content_setting_key = $this->get_repeater_setting_key( 'tab_content', 'tabs', $index );
$this->add_render_attribute( $tab_title_setting_key, [
'id' => 'elementor-tab-title-' . $id_int . $tab_count,
'class' => [ 'elementor-tab-title' ],
'data-tab' => $tab_count,
'role' => 'tab',
'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
'aria-expanded' => 'false',
] );
$this->add_render_attribute( $tab_content_setting_key, [
'id' => 'elementor-tab-content-' . $id_int . $tab_count,
'class' => [ 'elementor-tab-content', 'elementor-clearfix' ],
'data-tab' => $tab_count,
'role' => 'tabpanel',
'aria-labelledby' => 'elementor-tab-title-' . $id_int . $tab_count,
] );
$this->add_inline_editing_attributes( $tab_content_setting_key, 'advanced' );
?>
<div class="elementor-toggle-item">
<<?php echo Utils::validate_html_tag( $settings['title_html_tag'] ); ?> <?php echo $this->get_render_attribute_string( $tab_title_setting_key ); ?>>
<?php if ( $has_icon ) : ?>
<span class="elementor-toggle-icon elementor-toggle-icon-<?php echo esc_attr( $settings['icon_align'] ); ?>" aria-hidden="true">
<?php
if ( $is_new || $migrated ) { ?>
<span class="elementor-toggle-icon-closed"><?php Icons_Manager::render_icon( $settings['selected_icon'] ); ?></span>
<span class="elementor-toggle-icon-opened"><?php Icons_Manager::render_icon( $settings['selected_active_icon'], [ 'class' => 'elementor-toggle-icon-opened' ] ); ?></span>
<?php } else { ?>
<i class="elementor-toggle-icon-closed <?php echo esc_attr( $settings['icon'] ); ?>"></i>
<i class="elementor-toggle-icon-opened <?php echo esc_attr( $settings['icon_active'] ); ?>"></i>
<?php } ?>
</span>
<?php endif; ?>
<a href="" class="elementor-toggle-title"><?php echo $item['tab_title']; ?></a>
</<?php echo Utils::validate_html_tag( $settings['title_html_tag'] ); ?>>
<div <?php echo $this->get_render_attribute_string( $tab_content_setting_key ); ?>><?php echo $this->parse_text_editor( $item['tab_content'] ); ?></div>
</div>
<?php endforeach; ?>
<?php
if ( isset( $settings['faq_schema'] ) && 'yes' === $settings['faq_schema'] ) {
$json = [
'@context' => 'https://schema.org',
'@type' => 'FAQPage',
'mainEntity' => [],
];
foreach ( $settings['tabs'] as $index => $item ) {
$json['mainEntity'][] = [
'@type' => 'Question',
'name' => wp_strip_all_tags( $item['tab_title'] ),
'acceptedAnswer' => [
'@type' => 'Answer',
'text' => $this->parse_text_editor( $item['tab_content'] ),
],
];
}
?>
<script type="application/ld+json"><?php echo wp_json_encode( $json ); ?></script>
<?php } ?>
</div>
<?php
}
/**
* Render toggle widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {
?>
<div class="elementor-toggle" role="tablist">
<#
if ( settings.tabs ) {
var tabindex = view.getIDInt().toString().substr( 0, 3 ),
iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, {}, 'i' , 'object' ),
iconActiveHTML = elementor.helpers.renderIcon( view, settings.selected_active_icon, {}, 'i' , 'object' ),
migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' ),
titleHTMLTag = elementor.helpers.validateHTMLTag( settings.title_html_tag );
_.each( settings.tabs, function( item, index ) {
var tabCount = index + 1,
tabTitleKey = view.getRepeaterSettingKey( 'tab_title', 'tabs', index ),
tabContentKey = view.getRepeaterSettingKey( 'tab_content', 'tabs', index );
view.addRenderAttribute( tabTitleKey, {
'id': 'elementor-tab-title-' + tabindex + tabCount,
'class': [ 'elementor-tab-title' ],
'data-tab': tabCount,
'role': 'tab',
'aria-controls': 'elementor-tab-content-' + tabindex + tabCount,
'aria-expanded': 'false',
} );
view.addRenderAttribute( tabContentKey, {
'id': 'elementor-tab-content-' + tabindex + tabCount,
'class': [ 'elementor-tab-content', 'elementor-clearfix' ],
'data-tab': tabCount,
'role': 'tabpanel',
'aria-labelledby': 'elementor-tab-title-' + tabindex + tabCount
} );
view.addInlineEditingAttributes( tabContentKey, 'advanced' );
#>
<div class="elementor-toggle-item">
<{{{ titleHTMLTag }}} {{{ view.getRenderAttributeString( tabTitleKey ) }}}>
<# if ( settings.icon || settings.selected_icon ) { #>
<span class="elementor-toggle-icon elementor-toggle-icon-{{ settings.icon_align }}" aria-hidden="true">
<# if ( iconHTML && iconHTML.rendered && ( ! settings.icon || migrated ) ) { #>
<span class="elementor-toggle-icon-closed">{{{ iconHTML.value }}}</span>
<span class="elementor-toggle-icon-opened">{{{ iconActiveHTML.value }}}</span>
<# } else { #>
<i class="elementor-toggle-icon-closed {{ settings.icon }}"></i>
<i class="elementor-toggle-icon-opened {{ settings.icon_active }}"></i>
<# } #>
</span>
<# } #>
<a href="" class="elementor-toggle-title">{{{ item.tab_title }}}</a>
</{{{ titleHTMLTag }}}>
<div {{{ view.getRenderAttributeString( tabContentKey ) }}}>{{{ item.tab_content }}}</div>
</div>
<#
} );
} #>
</div>
<?php
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,316 @@
<?php
namespace Elementor;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor WordPress widget.
*
* Elementor widget that displays all the WordPress widgets.
*
* @since 1.0.0
*/
class Widget_WordPress extends Widget_Base {
/**
* WordPress widget name.
*
* @access private
*
* @var string
*/
private $_widget_name = null;
/**
* WordPress widget instance.
*
* @access private
*
* @var \WP_Widget
*/
private $_widget_instance = null;
/**
* Whether the widget is a Pojo widget or not.
*
* @since 2.0.0
* @access private
*
* @return bool
*/
private function is_pojo_widget() {
return $this->get_widget_instance() instanceof \Pojo_Widget_Base;
}
/**
* Get widget name.
*
* Retrieve WordPress/Pojo widget name.
*
* @since 1.0.0
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'wp-widget-' . $this->get_widget_instance()->id_base;
}
/**
* Get widget title.
*
* Retrieve WordPress/Pojo widget title.
*
* @since 1.0.0
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return $this->get_widget_instance()->name;
}
/**
* Get widget categories.
*
* Retrieve the list of categories the WordPress/Pojo widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* @since 1.0.0
* @access public
*
* @return array Widget categories. Returns either a WordPress category or Pojo category.
*/
public function get_categories() {
if ( $this->is_pojo_widget() ) {
$category = 'pojo';
} else {
$category = 'wordpress';
}
return [ $category ];
}
/**
* Get widget icon.
*
* Retrieve WordPress/Pojo widget icon.
*
* @since 1.0.0
* @access public
*
* @return string Widget icon. Returns either a WordPress icon or Pojo icon.
*/
public function get_icon() {
if ( $this->is_pojo_widget() ) {
return 'eicon-pojome';
}
return 'eicon-wordpress';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the widget belongs to.
*
* @since 2.1.0
* @access public
*
* @return array Widget keywords.
*/
public function get_keywords() {
return [ 'wordpress', 'widget' ];
}
public function get_help_url() {
return '';
}
/**
* Whether the reload preview is required or not.
*
* Used to determine whether the reload preview is required.
*
* @since 1.0.0
* @access public
*
* @return bool Whether the reload preview is required.
*/
public function is_reload_preview_required() {
return true;
}
/**
* Retrieve WordPress/Pojo widget form.
*
* Returns the WordPress widget form, to be used in Elementor.
*
* @since 1.0.0
* @access public
*
* @return string Widget form.
*/
public function get_form() {
$instance = $this->get_widget_instance();
ob_start();
echo '<div class="widget-inside media-widget-control"><div class="form wp-core-ui">';
echo '<input type="hidden" class="id_base" value="' . esc_attr( $instance->id_base ) . '" />';
echo '<input type="hidden" class="widget-id" value="widget-' . esc_attr( $this->get_id() ) . '" />';
echo '<div class="widget-content">';
$widget_data = $this->get_settings( 'wp' );
$instance->form( $widget_data );
do_action( 'in_widget_form', $instance, null, $widget_data );
echo '</div></div></div>';
return ob_get_clean();
}
/**
* Retrieve WordPress/Pojo widget instance.
*
* Returns an instance of WordPress widget, to be used in Elementor.
*
* @since 1.0.0
* @access public
*
* @return \WP_Widget
*/
public function get_widget_instance() {
if ( is_null( $this->_widget_instance ) ) {
global $wp_widget_factory;
if ( isset( $wp_widget_factory->widgets[ $this->_widget_name ] ) ) {
$this->_widget_instance = $wp_widget_factory->widgets[ $this->_widget_name ];
$this->_widget_instance->_set( 'REPLACE_TO_ID' );
} elseif ( class_exists( $this->_widget_name ) ) {
$this->_widget_instance = new $this->_widget_name();
$this->_widget_instance->_set( 'REPLACE_TO_ID' );
}
}
return $this->_widget_instance;
}
/**
* Retrieve WordPress/Pojo widget parsed settings.
*
* Returns the WordPress widget settings, to be used in Elementor.
*
* @access protected
* @since 2.3.0
*
* @return array Parsed settings.
*/
protected function get_init_settings() {
$settings = parent::get_init_settings();
if ( ! empty( $settings['wp'] ) ) {
$widget = $this->get_widget_instance();
$instance = $widget->update( $settings['wp'], [] );
$settings['wp'] = apply_filters( 'widget_update_callback', $instance, $settings['wp'], [], $widget );
}
return $settings;
}
/**
* Register WordPress/Pojo widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 3.1.0
* @access protected
*/
protected function register_controls() {
$this->add_control(
'wp',
[
'label' => __( 'Form', 'elementor' ),
'type' => Controls_Manager::WP_WIDGET,
'widget' => $this->get_name(),
'id_base' => $this->get_widget_instance()->id_base,
]
);
}
/**
* Render WordPress/Pojo widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
* @access protected
*/
protected function render() {
$default_widget_args = [
'widget_id' => $this->get_name(),
'before_widget' => '',
'after_widget' => '',
'before_title' => '<h5>',
'after_title' => '</h5>',
];
/**
* WordPress widget args.
*
* Filters the WordPress widget arguments when they are rendered in Elementor panel.
*
* @since 1.0.0
*
* @param array $default_widget_args Default widget arguments.
* @param Widget_WordPress $this The WordPress widget.
*/
$default_widget_args = apply_filters( 'elementor/widgets/wordpress/widget_args', $default_widget_args, $this );
$is_gallery_widget = 'wp-widget-media_gallery' === $this->get_name();
if ( $is_gallery_widget ) {
add_filter( 'wp_get_attachment_link', [ $this, 'add_lightbox_data_to_image_link' ], 10, 2 );
}
$this->get_widget_instance()->widget( $default_widget_args, $this->get_settings( 'wp' ) );
if ( $is_gallery_widget ) {
remove_filter( 'wp_get_attachment_link', [ $this, 'add_lightbox_data_to_image_link' ] );
}
}
/**
* Render WordPress/Pojo widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
protected function content_template() {}
/**
* WordPress/Pojo widget constructor.
*
* Used to run WordPress widget constructor.
*
* @since 1.0.0
* @access public
*
* @param array $data Widget data. Default is an empty array.
* @param array $args Widget arguments. Default is null.
*/
public function __construct( $data = [], $args = null ) {
$this->_widget_name = $args['widget_name'];
parent::__construct( $data, $args );
}
/**
* Render WordPress/Pojo widget as plain content.
*
* Override the default render behavior, don't render widget content.
*
* @since 1.0.0
* @access public
*
* @param array $instance Widget instance. Default is empty array.
*/
public function render_plain_content( $instance = [] ) {}
}