<?php
namespace Essential_Addons_Elementor\Elements;
use Elementor\Group_Control_Background;
use Elementor\Group_Control_Border;
use Elementor\Group_Control_Typography;
use Elementor\Icons_Manager;
use ElementsKit_Lite\Modules\Widget_Builder\Controls\Control_Type_Border;
// If this file is called directly, abort.
if (!defined( 'ABSPATH' ) ) {
exit;
}
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
class Code_Snippet extends Widget_Base {
public function get_name() {
return 'eael-code-snippet';
}
public function get_title() {
return esc_html__( 'Code Snippet', 'essential-addons-for-elementor-lite' );
}
public function get_icon() {
return 'eaicon-code-snippet';
}
public function get_categories() {
return [ 'essential-addons-elementor' ];
}
public function get_keywords() {
return [
'code',
'snippet',
'code snippet',
'code block',
'programming',
'ea code',
'ea',
'essential addons'
];
}
public function get_custom_help_url() {
return 'https://essential-addons.com/elementor/docs/ea-code-snippet/';
}
protected function register_controls() {
$this->start_controls_section(
'code_snippet_section',
[
'label' => esc_html__( 'Code Settings', 'essential-addons-for-elementor-lite' ),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'language',
[
'label' => __( 'Programming Language', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SELECT2,
'default' => 'html',
'options' => [
'html' => __( 'HTML', 'essential-addons-for-elementor-lite' ),
'css' => __( 'CSS', 'essential-addons-for-elementor-lite' ),
'scss' => __( 'SCSS', 'essential-addons-for-elementor-lite' ),
'php' => __( 'PHP', 'essential-addons-for-elementor-lite' ),
'py' => __( 'Python', 'essential-addons-for-elementor-lite' ),
'js' => __( 'JavaScript', 'essential-addons-for-elementor-lite' ),
'jsx' => __( 'React JS', 'essential-addons-for-elementor-lite' ),
'vue' => __( 'Vue JS', 'essential-addons-for-elementor-lite' ),
'ts' => __( 'TypeScript', 'essential-addons-for-elementor-lite' ),
'sql' => __( 'SQL', 'essential-addons-for-elementor-lite' ),
'json' => __( 'JSON', 'essential-addons-for-elementor-lite' ),
'xml' => __( 'XML', 'essential-addons-for-elementor-lite' ),
'java' => __( 'Java', 'essential-addons-for-elementor-lite' ),
'rd' => __( 'Ruby', 'essential-addons-for-elementor-lite' ),
'bash' => __( 'Bash', 'essential-addons-for-elementor-lite' ),
'yml' => __( 'YAML', 'essential-addons-for-elementor-lite' ),
'cpp' => __( 'C++', 'essential-addons-for-elementor-lite' ),
'cs' => __( 'C#', 'essential-addons-for-elementor-lite' ),
'go' => __( 'Go', 'essential-addons-for-elementor-lite' ),
'rs' => __( 'Rust', 'essential-addons-for-elementor-lite' ),
'swift' => __( 'Swift', 'essential-addons-for-elementor-lite' ),
'kt' => __( 'Kotlin', 'essential-addons-for-elementor-lite' ),
'md' => __( 'Markdown', 'essential-addons-for-elementor-lite' ),
'sh' => __( 'Shell', 'essential-addons-for-elementor-lite' ),
'ps1' => __( 'Powershell', 'essential-addons-for-elementor-lite' ),
'dockerfile' => __( 'Docker', 'essential-addons-for-elementor-lite' ),
],
'description' => __( 'Choose language for syntax highlighting.', 'essential-addons-for-elementor-lite' ),
]
);
$this->add_control(
'code_content',
[
'label' => __( 'Code Snippet', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::CODE,
'language' => 'html',
'rows' => 15,
'default' => "// Paste or type your code hereβ¦",
'placeholder' => __( 'Enter your code snippet here...', 'essential-addons-for-elementor-lite' ),
'description' => __( 'Type or paste your code here. Use Tab to indent; syntax highlighting will appear in the live preview.', 'essential-addons-for-elementor-lite' ),
'ai' => [
'active' => false,
]
]
);
$this->end_controls_section();
$this->start_controls_section(
'appearance_section',
[
'label' => esc_html__( 'Appearance', 'essential-addons-for-elementor-lite' ),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'theme',
[
'label' => __( 'Theme', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::CHOOSE,
'default' => 'light',
'toggle' => false,
'options' => [
'light' => [
'title' => __( 'Light', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-light-mode',
],
'dark' => [
'title' => __( 'Dark', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-dark-mode',
],
],
'description' => __( 'Choose light or dark styling for the code snippet block.', 'essential-addons-for-elementor-lite' ),
]
);
$this->add_control(
'show_header',
[
'label' => __( 'Header bar', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'essential-addons-for-elementor-lite' ),
'label_off' => __( 'Hide', 'essential-addons-for-elementor-lite' ),
'return_value' => 'yes',
'default' => 'yes',
'description' => __( 'Toggle the filename header and copy button.', 'essential-addons-for-elementor-lite' ),
]
);
$this->add_control(
'show_copy_button',
[
'label' => __( 'Copy button', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'essential-addons-for-elementor-lite' ),
'label_off' => __( 'Hide', 'essential-addons-for-elementor-lite' ),
'return_value' => 'yes',
'default' => 'yes',
'description' => __( 'Show a one-click copy-to-clipboard icon.', 'essential-addons-for-elementor-lite' ),
'condition' => [
'show_header' => 'yes',
],
]
);
$this->add_control(
'show_copy_tooltip',
[
'label' => __( 'Copy button tooltip', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'essential-addons-for-elementor-lite' ),
'label_off' => __( 'Hide', 'essential-addons-for-elementor-lite' ),
'return_value' => 'yes',
'default' => 'no',
'description' => __( 'Display a tooltip (βCopied!β) on copy button hover or click.', 'essential-addons-for-elementor-lite' ),
'condition' => [
'show_header' => 'yes',
'show_copy_button' => 'yes',
],
]
);
$this->add_control(
'show_line_numbers',
[
'label' => __( 'Line numbers', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'essential-addons-for-elementor-lite' ),
'label_off' => __( 'Hide', 'essential-addons-for-elementor-lite' ),
'return_value' => 'yes',
'default' => 'no',
'description' => __( 'Display line numbers in the code block.', 'essential-addons-for-elementor-lite' ),
]
);
$this->add_control(
'code_view_mode',
[
'label' => esc_html__( 'View Mode', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'default' => [
'title' => esc_html__( 'Default', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-menu-toggle',
],
'fixed' => [
'title' => esc_html__( 'Fixed', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-spacer',
],
'collapsed' => [
'title' => esc_html__( 'Collapsed', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-v-align-stretch',
],
],
'default' => 'default',
'toggle' => false,
]
);
$this->add_responsive_control(
'code_snippet_height',
[
'label' => esc_html__( 'Height', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem' ],
'range' => [
'px' => [
'min' => 0,
'max' => 1000,
'step' => 5,
],
'em' => [
'min' => 0,
'max' => 100,
'step' => 0.5,
],
'rem' => [
'min' => 0,
'max' => 100,
'step' => 0.5,
],
],
'default' => [
'unit' => 'px',
'size' => 300,
],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-content' => 'height: {{SIZE}}{{UNIT}};',
],
'condition' => [
'code_view_mode!' => 'default',
],
]
);
$this->add_control(
'code_collapse_inidicator_content',
[
'label' => esc_html__( 'Indicator', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
'condition' => [
'code_view_mode' => 'collapsed',
],
]
);
$this->add_control(
'code_collapse_inidicator_type',
[
'label' => esc_html__( 'Type', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'full_width' => [
'title' => esc_html__( 'Full Width', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-text-align-justify',
],
'button' => [
'title' => esc_html__( 'Button', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-button',
],
],
'default' => 'full_width',
'toggle' => false,
'condition' => [
'code_view_mode' => 'collapsed',
],
]
);
$this->add_control(
'code_collapse_inidicator_position',
[
'label' => esc_html__( 'Position', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => esc_html__( 'Left', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => esc_html__( 'Right', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-text-align-right',
],
],
'default' => '',
'toggle' => true,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper' => 'justify-content: {{VALUE}};',
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-cs-indicator-type-full_width' => 'justify-content: {{VALUE}};',
],
'condition' => [
'code_view_mode' => 'collapsed',
],
]
);
$this->add_control(
'code_collapse_inidicator_content_type',
[
'label' => esc_html__( 'Content Type', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'text' => [
'title' => esc_html__( 'Text', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-animation-text',
],
'icon' => [
'title' => esc_html__( 'Icon', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-favorite',
],
],
'default' => 'text',
'toggle' => false,
'condition' => [
'code_view_mode' => 'collapsed',
],
]
);
$this->add_control(
'code_collapse_inidicator_text_collapsed',
[
'label' => esc_html__( 'Text (Collapsed)', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Show more', 'essential-addons-for-elementor-lite' ),
'ai' => [
'active' => true,
],
'condition' => [
'code_view_mode' => 'collapsed',
'code_collapse_inidicator_content_type' => 'text',
],
]
);
$this->add_control(
'code_collapse_inidicator_text_expanded',
[
'label' => esc_html__( 'Text (Expanded)', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Show less', 'essential-addons-for-elementor-lite' ),
'ai' => [
'active' => true,
],
'condition' => [
'code_view_mode' => 'collapsed',
'code_collapse_inidicator_content_type' => 'text',
],
]
);
$this->add_control(
'code_collapse_inidicator_icon_collapsed',
[
'label' => esc_html__( 'Icon (Collapsed)', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::ICONS,
'default' => [
'value' => 'fas fa-angle-down',
'library' => 'fa-solid',
],
'condition' => [
'code_view_mode' => 'collapsed',
'code_collapse_inidicator_content_type' => 'icon',
],
]
);
$this->add_control(
'code_collapse_inidicator_icon_expanded',
[
'label' => esc_html__( 'Icon (Expanded)', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::ICONS,
'default' => [
'value' => 'fas fa-angle-up',
'library' => 'fa-solid',
],
'condition' => [
'code_view_mode' => 'collapsed',
'code_collapse_inidicator_content_type' => 'icon',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'file_preview_section',
[
'label' => __( 'Header', 'essential-addons-for-elementor-lite' ),
'tab' => Controls_Manager::TAB_CONTENT,
'condition' => [
'show_header' => 'yes',
],
]
);
$this->add_control(
'file_name',
[
'label' => __( 'File Name', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::TEXT,
'default' => 'filename',
'placeholder' => __( 'Enter filename with extension', 'essential-addons-for-elementor-lite' ),
'description' => __( 'Enter the filename to display in the header (e.g., hero-section.tsx)', 'essential-addons-for-elementor-lite' ),
'ai' => [ 'active' => true ],
'dynamic' => [ 'active' => true ],
]
);
$this->add_control(
'show_traffic_lights',
[
'label' => __( 'Window buttons', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'essential-addons-for-elementor-lite' ),
'label_off' => __( 'Hide', 'essential-addons-for-elementor-lite' ),
'return_value' => 'yes',
'default' => 'yes',
'description' => __( 'Display macOS-style close/minimize/maximize circles.', 'essential-addons-for-elementor-lite' ),
]
);
$this->add_control(
'show_file_icon',
[
'label' => __( 'Language icon', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'essential-addons-for-elementor-lite' ),
'label_off' => __( 'Hide', 'essential-addons-for-elementor-lite' ),
'return_value' => 'yes',
'default' => 'yes',
'description' => __( 'Display the default icon for this file type.', 'essential-addons-for-elementor-lite' ),
]
);
$this->add_control(
'file_icon_type',
[
'label' => esc_html__( 'Icon Type', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'image' => [
'title' => esc_html__( 'Image', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-image',
],
'icon' => [
'title' => esc_html__( 'Icon', 'essential-addons-for-elementor-lite' ),
'icon' => 'eicon-favorite',
],
],
'default' => 'image',
'toggle' => true,
'condition' => [
'show_file_icon' => 'yes',
],
]
);
$this->add_control(
'file_icon',
[
'label' => '',
'type' => Controls_Manager::MEDIA,
// 'media_types' => [ 'image' ],
'description' => __( 'Upload a custom icon to override the default.', 'essential-addons-for-elementor-lite' ),
'condition' => [
'show_file_icon' => 'yes',
'file_icon_type' => 'image',
],
'ai' => [
'active' => false,
],
]
);
$this->add_control(
'file_icon_custom',
[
'label' => '',
'type' => Controls_Manager::ICONS,
'fa4compatibility' => 'icon',
'condition' => [
'show_file_icon' => 'yes',
'file_icon_type' => 'icon',
],
]
);
$this->end_controls_section();
// Style Tab - Wrapper
$this->start_controls_section(
'wrapper_style_section',
[
'label' => esc_html__( 'Wrapper', 'essential-addons-for-elementor-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'wrapper_margin',
[
'label' => __( 'Margin', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-wrapper' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'wrapper_padding',
[
'label' => __( 'Padding', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-wrapper' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_control(
'wrapper_background_color',
[
'label' => __( 'Background Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-wrapper' => 'background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'wrapper_border',
'selector' => '{{WRAPPER}} .eael-code-snippet-wrapper',
]
);
$this->add_control(
'wrapper_border_radius',
[
'label' => esc_html__( 'Border Radius', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-wrapper' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
// Style Tab - Header
$this->start_controls_section(
'header_style_section',
[
'label' => __( 'Header', 'essential-addons-for-elementor-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'show_header' => 'yes',
],
]
);
$this->add_responsive_control(
'header_padding',
[
'label' => __( 'Padding', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-header.eael-file-preview-header' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_control(
'header_background_color',
[
'label' => __( 'Background Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-header.eael-file-preview-header' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'header_border_color',
[
'label' => __( 'Border Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-header.eael-file-preview-header' => 'border-bottom-color: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'header_border_width',
[
'label' => __( 'Border Width', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'range' => [
'px' => [
'min' => 0,
'max' => 10,
],
],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-header.eael-file-preview-header' => 'border-bottom-width: {{SIZE}}{{UNIT}}; border-bottom-style: solid;',
],
'description' => __( 'Controls border bottom width', 'essential-addons-for-elementor-lite' ),
]
);
$this->add_control(
'file_custom_icon_style_heading',
[
'label' => esc_html__( 'File Icon', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
'condition' => [
'show_file_icon' => 'yes',
'file_icon_type' => 'icon',
],
]
);
$this->add_control(
'file_custom_icon_color',
[
'label' => __( 'Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-file-icon i' => 'color: {{VALUE}};',
'{{WRAPPER}} .eael-file-icon svg' => 'fill: {{VALUE}};',
],
'condition' => [
'show_file_icon' => 'yes',
'file_icon_type' => 'icon',
],
]
);
$this->add_control(
'file_name_style_heading',
[
'label' => esc_html__( 'File Name', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'file_name_typography',
'label' => __( 'Typography', 'essential-addons-for-elementor-lite' ),
'selector' => '{{WRAPPER}} .eael-code-snippet-header .file-name-text',
]
);
$this->add_control(
'file_name_color',
[
'label' => __( 'Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-header .file-name-text' => 'color: {{VALUE}};',
],
]
);
$this->add_control(
'copy_button_style_heading',
[
'label' => esc_html__( 'Copy Button', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
'condition' => [
'show_copy_button' => 'yes',
],
]
);
$this->add_control(
'copy_button_color',
[
'label' => __( 'Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-copy-button' => 'color: {{VALUE}};',
],
'condition' => [
'show_copy_button' => 'yes',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'copy_button_border',
'selector' => '{{WRAPPER}} .eael-code-snippet-copy-button',
]
);
$this->add_responsive_control(
'copy_button_border_radius',
[
'label' => esc_html__( 'Border Radius', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-copy-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
// Style Tab - Line Numbers
$this->start_controls_section(
'line_numbers_style_section',
[
'label' => __( 'Line Numbers', 'essential-addons-for-elementor-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'show_line_numbers' => 'yes',
],
]
);
$this->add_responsive_control(
'line_numbers_padding',
[
'label' => __( 'Padding', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-line-numbers' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_control(
'line_numbers_color',
[
'label' => __( 'Line Number Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-line-numbers .line-number' => 'color: {{VALUE}};',
],
]
);
$this->add_control(
'line_numbers_background_color',
[
'label' => __( 'Line Number Background', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-line-numbers' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'line_numbers_border_color',
[
'label' => __( 'Border Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-line-numbers' => 'border-right-color: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'line_numbers_border_width',
[
'label' => __( 'Border Width', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'range' => [
'px' => [
'min' => 0,
'max' => 20,
],
],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-line-numbers' => 'border-right-width: {{SIZE}}{{UNIT}}; border-right-style: solid;',
],
'description' => __( 'Controls border right width', 'essential-addons-for-elementor-lite' ),
]
);
$this->end_controls_section();
// Style Tab - Code Content Area
$this->start_controls_section(
'code_content_style_section',
[
'label' => __( 'Code Content Area', 'essential-addons-for-elementor-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'code_content_padding',
[
'label' => __( 'Padding', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', '%' ],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-code' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_control(
'code_content_background_color',
[
'label' => __( 'Background Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-code' => 'background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'content_typography',
'selector' => '{{WRAPPER}} .eael-code-snippet-line-numbers, {{WRAPPER}} .eael-code-snippet-code, {{WRAPPER}} .eael-code-snippet-code code',
]
);
$this->end_controls_section();
// Style Tab - Code Content
$this->start_controls_section(
'code_content_collapse_style_section',
[
'label' => __( 'Collapse Indicator', 'essential-addons-for-elementor-lite' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'code_view_mode' => 'collapsed',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'code_content_collapsed_indicator_typography',
'selector' => '{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator .eael-code-snippet-collapsed-indicator-text',
'condition' => [
'code_collapse_inidicator_content_type' => 'text'
]
]
);
$this->add_responsive_control(
'code_content_collapsed_indicator_icon_size',
[
'label' => esc_html__( 'Icon Size', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem' ],
'range' => [
'px' => [
'min' => 0,
'max' => 1000,
'step' => 5,
],
],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator i' => 'font-size: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator svg' => 'height: {{SIZE}}{{UNIT}}; width: {{SIZE}}{{UNIT}};',
],
'condition' => [
'code_collapse_inidicator_content_type' => 'icon'
]
]
);
$this->add_control(
'code_content_collapsed_indicator_color',
[
'label' => __( 'Color', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator i' => 'color: {{VALUE}};',
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator svg' => 'fill: {{VALUE}};',
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator .eael-code-snippet-collapsed-indicator-text' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'code_content_collapsed_indicator_background',
'types' => [ 'classic', 'gradient' ],
'exclude' => [ 'image' ],
'selector' => '{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator',
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'code_content_collapsed_indicator_border',
'selector' => '{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator',
]
);
$this->add_responsive_control(
'code_content_collapsed_indicator_border_radius',
[
'label' => __( 'Border Radius', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%' ],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'code_content_collapsed_indicator_height',
[
'label' => esc_html__( 'Height', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
'step' => 5,
],
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'unit' => 'px',
'size' => 30,
],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper' => 'height: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator' => 'height: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'code_content_collapsed_indicator_width',
[
'label' => esc_html__( 'Width', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
'step' => 5,
],
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'unit' => 'px',
'size' => 30,
],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator.eael-cs-indicator-type-button' => 'width: {{SIZE}}{{UNIT}};',
],
'condition' => [
'code_view_mode' => 'collapsed',
'code_collapse_inidicator_type' => 'button',
],
]
);
$this->add_responsive_control(
'code_content_collapsed_indicator_padding',
[
'label' => esc_html__( 'Padding', 'essential-addons-for-elementor-lite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em', 'rem' ],
'default' => [
'top' => 20,
'right' => 20,
'bottom' => 20,
'left' => 20,
'unit' => 'px',
'isLinked' => true,
],
'selectors' => [
'{{WRAPPER}} .eael-code-snippet-collapsed-indicator-wrapper .eael-code-snippet-collapsed-indicator.eael-cs-indicator-type-full_width' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'code_view_mode' => 'collapsed',
'code_collapse_inidicator_type' => 'full_width',
],
]
);
$this->end_controls_section();
}
/**
* Get default file icon based on programming language
* @return string Emoji icon for the language
*/
public static function get_file_icon_by_language( $language ) {
$icons = [
'html' => 'π',
'css' => 'π¨',
'scss' => 'π¨',
'php' => 'π',
'py' => 'π',
'js' => 'π',
'jsx' => 'βοΈ',
'vue' => 'π©',
'ts' => 'π',
'sql' => 'ποΈ',
'json' => 'π',
'xml' => 'π',
'java' => 'β',
'rd' => 'π',
'bash' => 'π»',
'yml' => 'π',
'cpp' => 'ββ',
'cs' => 'π·',
'go' => 'πΉ',
'rs' => 'π¦',
'swift' => 'π¦',
'kt' => 'π―',
'md' => 'π',
'sh' => 'π»',
'ps1' => 'π',
'dockerfile' => 'π³',
];
return $icons[$language] ?? 'π';
}
protected function render() {
$settings = $this->get_settings_for_display();
// Generate unique snippet ID for this widget instance
$snippet_id = 'eael-code-snippet-' . $this->get_id();
// Generate line numbers if needed
$line_numbers = [];
if ( $settings['show_line_numbers'] ) {
$lines = explode( "\n", $settings['code_content'] );
$line_numbers = range( 1, count( $lines ) );
}
$file_icon = !empty($settings['file_icon']['url']) || !empty($settings['file_icon_custom']['value']) ?? '';
$show_file_icon = $settings['show_file_icon'] ?? 'yes';
$language = $settings['language'] ?? 'html';
$file_name = $settings['file_name'] ?? '';
$theme = $settings['theme'] ?? 'light';
$show_traffic_lights = $settings['show_traffic_lights'] ?? 'yes';
$show_line_numbers = $settings['show_line_numbers'] ?? 'no';
$show_header = $settings['show_header'] ?? 'yes';
$show_copy_button = $settings['show_copy_button'] ?? 'yes';
$show_copy_tooltip = $settings['show_copy_tooltip'] ?? 'no';
$this->add_render_attribute( 'eael-snippet-wrapper', 'class', 'eael-code-snippet-wrapper theme-' . $theme );
$this->add_render_attribute( 'eael-snippet-wrapper', 'data-language', $language );
$this->add_render_attribute( 'eael-snippet-wrapper', 'data-copy-button', 'yes' === $show_copy_button );
$this->add_render_attribute( 'eael-snippet-wrapper', 'data-snippet-id', $snippet_id );
$this->add_render_attribute( 'eael-snippet-wrapper', 'id', $snippet_id );
$this->add_render_attribute( 'eael-snippet-wrapper', 'class', 'view-mode-' . $settings['code_view_mode'] );
?>
<div <?php $this->print_render_attribute_string( 'eael-snippet-wrapper' ); ?> >
<?php if ( 'yes' === $show_header ) { ?>
<div class="eael-code-snippet-header eael-file-preview-header">
<div class="eael-file-preview-left">
<?php if ( 'yes' === $show_traffic_lights ) { ?>
<div class="eael-traffic-lights">
<span class="traffic-light traffic-light-red"></span>
<span class="traffic-light traffic-light-yellow"></span>
<span class="traffic-light traffic-light-green"></span>
</div>
<?php } ?>
<div class="eael-file-info">
<?php if ( 'yes' === $show_file_icon ) { ?>
<div class="eael-file-icon">
<?php if ( ! empty( $file_icon ) ) {
if ( $settings['file_icon_type'] === 'icon' ) {
Icons_Manager::render_icon( $settings['file_icon_custom'], [ 'aria-hidden' => 'true' ] );
} else {
echo wp_get_attachment_image( $settings['file_icon']['id'], 'thumbnail', true, [ 'alt' => esc_attr__( 'File icon', 'essential-addons-for-elementor-lite' ) ] );
}
} else {
?>
<span class="eael-file-icon-emoji"><?php echo esc_html( self::get_file_icon_by_language( $language ) ); ?></span>
<?php
} ?>
</div>
<?php }
if ( ! empty( $file_name ) ) { ?>
<div class="eael-file-name">
<span class="file-name-text">
<?php
if ( strpos( $file_name, '.' ) === false && ! empty( $language ) ) {
echo esc_html( $file_name . '.' . $language );
} else {
echo esc_html( $file_name );
}
?>
</span>
</div>
<?php } ?>
</div>
</div>
<?php if ( 'yes' === $show_copy_button ) {
$this->add_render_attribute( 'eael-code-snippet-copy-button', [
'data-clipboard-target' => '#' . esc_attr( $snippet_id ) . ' .eael-code-snippet-code code',
'class' => 'eael-code-snippet-copy-button',
'type' => 'button',
'aria-label' => esc_attr__( 'Copy code to clipboard', 'essential-addons-for-elementor-lite' )
] );
$this->add_render_attribute( 'eael-code-snippet-copy-button', 'aria-label', esc_attr__( 'Copy code to clipboard', 'essential-addons-for-elementor-lite' ) );
?>
<div class="eael-file-preview-right">
<div class="eael-code-snippet-copy-container">
<button <?php $this->print_render_attribute_string( 'eael-code-snippet-copy-button' ); ?>>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 1H4C2.9 1 2 1.9 2 3V17H4V3H16V1ZM19 5H8C6.9 5 6 5.9 6 7V21C6 22.1 6.9 23 8 23H19C20.1 23 21 22.1 21 21V7C21 5.9 20.1 5 19 5ZM19 21H8V7H19V21Z" fill="currentColor"/>
</svg>
</button>
<?php if ( 'yes' === $show_copy_tooltip ) { ?>
<div class="eael-code-snippet-tooltip"><?php esc_html_e( 'Copy to clipboard', 'essential-addons-for-elementor-lite' ); ?></div>
<?php } ?>
</div>
</div>
<?php } ?>
</div>
<?php } ?>
<div class="eael-code-snippet-content">
<?php if( 'yes' === $show_line_numbers ) { ?>
<div class="eael-code-snippet-line-numbers" aria-hidden="true">
<?php foreach ( $line_numbers as $line_number ) { ?>
<div class="line-number"><?php echo esc_html( $line_number ); ?></div>
<?php } ?>
</div>
<?php } ?>
<pre class="eael-code-snippet-code language-<?php echo esc_attr( $language ); ?>"><code><?php echo esc_html( $settings['code_content'] ); ?></code></pre>
<?php if( 'collapsed' === $settings['code_view_mode'] ) {
$indcator_type_class = !empty($settings['code_collapse_inidicator_type']) ? 'eael-cs-indicator-type-' . $settings['code_collapse_inidicator_type'] : '';
$this->add_render_attribute( 'eael_code_snippet_view_mode', [
'class' => [
'eael-code-snippet-collapsed-indicator',
$indcator_type_class,
'eael-cs-code-collapsed'
]
] );
?>
<div class="eael-code-snippet-collapsed-indicator-wrapper">
<div <?php $this->print_render_attribute_string( 'eael_code_snippet_view_mode' ); ?>>
<?php if ( 'text' === $settings['code_collapse_inidicator_content_type'] ) { ?>
<span class="eael-code-snippet-collapsed-indicator-text eael-csi-collapsed"><?php echo esc_html( $settings['code_collapse_inidicator_text_collapsed'] ); ?></span>
<span class="eael-code-snippet-collapsed-indicator-text eael-csi-expanded"><?php echo esc_html( $settings['code_collapse_inidicator_text_expanded'] ); ?></span>
<?php } else { ?>
<?php Icons_Manager::render_icon( $settings['code_collapse_inidicator_icon_collapsed'], [ 'aria-hidden' => 'true', 'class' => 'eael-code-snippet-collapsed-indicator-icon eael-csi-collapsed' ] ); ?>
<?php Icons_Manager::render_icon( $settings['code_collapse_inidicator_icon_expanded'], [ 'aria-hidden' => 'true', 'class' => 'eael-code-snippet-collapsed-indicator-icon eael-csi-expanded' ] ); ?>
<?php } ?>
</div>
</div>
<?php } ?>
</div>
</div>
<?php
}
}