*/ public function get_style_depends(): array { return [KING_ADDONS_ASSETS_UNIQUE_KEY . '-testimonials-wall-style']; } /** * Script dependencies. * * @return array */ public function get_script_depends(): array { $handle = KING_ADDONS_ASSETS_UNIQUE_KEY . '-testimonials-wall-script'; // Elementor may call enqueue_scripts before the widget settings are available. // Therefore, get_script_depends() must not access settings. // The script itself may "do nothing" if the feature is disabled via settings. return [$handle]; } /** * Widget categories. * * @return array */ public function get_categories(): array { return ['king-addons']; } /** * Widget keywords. * * @return array */ public function get_keywords(): array { return [ 'testimonials', 'reviews', 'wall', 'masonry', 'grid', 'ratings', 'filters', 'load more', 'king', 'addons', 'kingaddons', 'king-addons', ]; } /** * Widget help URL. * * @return string */ public function get_custom_help_url() { return 'mailto:bug@kingaddons.com?subject=Bug Report - King Addons&body=Please describe the issue'; } /** * Register widget controls. * * @return void */ public function register_controls(): void { $this->register_content_controls(); $this->register_display_controls(); $this->register_layout_controls(); $this->register_filter_controls(); $this->register_load_more_controls(); $this->register_empty_state_controls(); $this->register_editor_controls(); $this->register_style_controls(); $this->register_pro_notice_controls(); } /** * Register content controls. * * @return void */ protected function register_content_controls(): void { $this->start_controls_section( 'kng_tw_content_section', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Testimonials', 'king-addons'), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $repeater = new Repeater(); $repeater->add_control( 'kng_tw_name', [ 'label' => esc_html__('Author Name', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('Alex Johnson', 'king-addons'), 'label_block' => true, ] ); $repeater->add_control( 'kng_tw_title', [ 'label' => esc_html__('Author Title', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('Product Lead', 'king-addons'), 'label_block' => true, ] ); $repeater->add_control( 'kng_tw_company', [ 'label' => esc_html__('Company', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('Flux Labs', 'king-addons'), 'label_block' => true, ] ); $repeater->add_control( 'kng_tw_avatar', [ 'label' => esc_html__('Avatar', 'king-addons'), 'type' => Controls_Manager::MEDIA, 'default' => [ 'url' => Utils::get_placeholder_image_src(), ], ] ); $repeater->add_control( 'kng_tw_rating', [ 'label' => esc_html__('Rating (1-5)', 'king-addons'), 'type' => Controls_Manager::NUMBER, 'min' => 0, 'max' => 5, 'step' => 1, 'default' => 5, ] ); $repeater->add_control( 'kng_tw_date', [ 'label' => esc_html__('Date', 'king-addons'), 'type' => Controls_Manager::DATE_TIME, 'label_block' => true, ] ); $repeater->add_control( 'kng_tw_text', [ 'label' => esc_html__('Review Text', 'king-addons'), 'type' => Controls_Manager::TEXTAREA, 'rows' => 6, 'default' => esc_html__('Fast onboarding, great support, and the wall layout makes our social proof feel alive.', 'king-addons'), ] ); $repeater->add_control( 'kng_tw_source', [ 'label' => esc_html__('Source Label', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('Google', 'king-addons'), ] ); $repeater->add_control( 'kng_tw_categories', [ 'label' => esc_html__('Categories (comma-separated)', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('SaaS, Support', 'king-addons'), 'label_block' => true, ] ); $repeater->add_control( 'kng_tw_featured', [ 'label' => sprintf(__('Featured %s', 'king-addons'), ''), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', 'separator' => 'before', 'classes' => 'king-addons-pro-control no-distance', ] ); $default_items = [ [ 'kng_tw_name' => esc_html__('Alex Johnson', 'king-addons'), 'kng_tw_title' => esc_html__('Product Lead', 'king-addons'), 'kng_tw_company' => esc_html__('Flux Labs', 'king-addons'), 'kng_tw_rating' => 5, 'kng_tw_text' => esc_html__('Fast onboarding, great support, and the wall layout makes our social proof feel alive.', 'king-addons'), 'kng_tw_source' => esc_html__('Google', 'king-addons'), 'kng_tw_categories' => esc_html__('SaaS, Support', 'king-addons'), ], [ 'kng_tw_name' => esc_html__('Maya Lee', 'king-addons'), 'kng_tw_title' => esc_html__('Founder', 'king-addons'), 'kng_tw_company' => esc_html__('Studio North', 'king-addons'), 'kng_tw_rating' => 5, 'kng_tw_text' => esc_html__('We replaced the old carousel with the wall and conversion improved instantly.', 'king-addons'), 'kng_tw_source' => esc_html__('Upwork', 'king-addons'), 'kng_tw_categories' => esc_html__('Agency, Conversion', 'king-addons'), ], [ 'kng_tw_name' => esc_html__('Jonas Weber', 'king-addons'), 'kng_tw_title' => esc_html__('CX Manager', 'king-addons'), 'kng_tw_company' => esc_html__('Cloudline', 'king-addons'), 'kng_tw_rating' => 4, 'kng_tw_text' => esc_html__('Smooth filters and the masonry vibe make it feel modern without the heavy JS.', 'king-addons'), 'kng_tw_source' => esc_html__('Trustpilot', 'king-addons'), 'kng_tw_categories' => esc_html__('SaaS, UI', 'king-addons'), ], [ 'kng_tw_name' => esc_html__('Sophia Grant', 'king-addons'), 'kng_tw_title' => esc_html__('Marketing Lead', 'king-addons'), 'kng_tw_company' => esc_html__('Orbit AI', 'king-addons'), 'kng_tw_rating' => 5, 'kng_tw_text' => esc_html__('Search + rating filters help visitors quickly find relevant stories.', 'king-addons'), 'kng_tw_source' => esc_html__('G2', 'king-addons'), 'kng_tw_categories' => esc_html__('B2B, Growth', 'king-addons'), ], [ 'kng_tw_name' => esc_html__('Liam Perez', 'king-addons'), 'kng_tw_title' => esc_html__('Operations', 'king-addons'), 'kng_tw_company' => esc_html__('BrightPath', 'king-addons'), 'kng_tw_rating' => 4, 'kng_tw_text' => esc_html__('The load more feel keeps the page light but still rich in proof.', 'king-addons'), 'kng_tw_source' => esc_html__('LinkedIn', 'king-addons'), 'kng_tw_categories' => esc_html__('Services, Operations', 'king-addons'), ], [ 'kng_tw_name' => esc_html__('Ivy Chen', 'king-addons'), 'kng_tw_title' => esc_html__('Designer', 'king-addons'), 'kng_tw_company' => esc_html__('Layer Studio', 'king-addons'), 'kng_tw_rating' => 5, 'kng_tw_text' => esc_html__('Love the dense layout and the subtle hover lift.', 'king-addons'), 'kng_tw_source' => esc_html__('Behance', 'king-addons'), 'kng_tw_categories' => esc_html__('Design, Studio', 'king-addons'), ], ]; foreach ($default_items as &$item) { $item['kng_tw_avatar'] = [ 'url' => Utils::get_placeholder_image_src(), ]; } unset($item); $this->add_control( 'kng_tw_items', [ 'type' => Controls_Manager::REPEATER, 'fields' => $repeater->get_controls(), 'default' => $default_items, 'title_field' => '{{kng_tw_name}}', ] ); $this->add_group_control( Group_Control_Image_Size::get_type(), [ 'name' => 'kng_tw_avatar_size', 'default' => 'thumbnail', ] ); $this->end_controls_section(); } /** * Register display toggles. * * @return void */ protected function register_display_controls(): void { $this->start_controls_section( 'kng_tw_display_section', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Display', 'king-addons'), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'kng_tw_show_avatar', [ 'label' => esc_html__('Show Avatar', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', ] ); $this->add_control( 'kng_tw_show_meta', [ 'label' => esc_html__('Show Author Meta', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', ] ); $this->add_control( 'kng_tw_show_rating', [ 'label' => esc_html__('Show Rating', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', ] ); $this->add_control( 'kng_tw_show_date', [ 'label' => esc_html__('Show Date', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', ] ); $this->add_control( 'kng_tw_show_source', [ 'label' => esc_html__('Show Source Label', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', ] ); $this->add_control( 'kng_tw_enable_read_more', [ 'label' => esc_html__('Enable Read More', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', ] ); $this->add_control( 'kng_tw_read_more_lines', [ 'label' => esc_html__('Collapsed Lines', 'king-addons'), 'type' => Controls_Manager::NUMBER, 'min' => 2, 'max' => 12, 'step' => 1, 'default' => 4, 'condition' => [ 'kng_tw_enable_read_more' => 'yes', ], ] ); $this->add_control( 'kng_tw_read_more_text', [ 'label' => esc_html__('Read More Text', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('Read more', 'king-addons'), 'condition' => [ 'kng_tw_enable_read_more' => 'yes', ], ] ); $this->add_control( 'kng_tw_read_less_text', [ 'label' => esc_html__('Read Less Text', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('Read less', 'king-addons'), 'condition' => [ 'kng_tw_enable_read_more' => 'yes', ], ] ); $this->end_controls_section(); } /** * Register layout controls. * * @return void */ protected function register_layout_controls(): void { $this->start_controls_section( 'kng_tw_layout_section', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Layout', 'king-addons'), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'kng_tw_layout', [ 'label' => esc_html__('Layout Mode', 'king-addons'), 'type' => Controls_Manager::SELECT, 'options' => [ 'masonry' => esc_html__('Masonry', 'king-addons'), 'grid' => esc_html__('Grid', 'king-addons'), ], 'default' => 'masonry', ] ); $this->add_responsive_control( 'kng_tw_columns', [ 'label' => esc_html__('Columns', 'king-addons'), 'type' => Controls_Manager::NUMBER, 'min' => 1, 'max' => 6, 'step' => 1, 'desktop_default' => 3, 'tablet_default' => 2, 'mobile_default' => 1, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-cols: {{SIZE}};', ], ] ); $this->add_responsive_control( 'kng_tw_gap', [ 'label' => esc_html__('Gap', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', 'em', 'rem'], 'range' => [ 'px' => ['min' => 0, 'max' => 60], 'em' => ['min' => 0, 'max' => 3], 'rem' => ['min' => 0, 'max' => 3], ], 'default' => [ 'size' => 24, 'unit' => 'px', ], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-gap: {{SIZE}}{{UNIT}};', ], ] ); $this->add_responsive_control( 'kng_tw_item_min_width', [ 'label' => esc_html__('Item Min Width', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', 'em', 'rem'], 'range' => [ 'px' => ['min' => 120, 'max' => 480], 'em' => ['min' => 8, 'max' => 30], 'rem' => ['min' => 8, 'max' => 30], ], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-item-min: {{SIZE}}{{UNIT}};', ], ] ); $this->add_responsive_control( 'kng_tw_masonry_row_height', [ 'label' => esc_html__('Masonry Row Height', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px'], 'range' => [ 'px' => ['min' => 4, 'max' => 20], ], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-row: {{SIZE}}{{UNIT}};', ], 'condition' => [ 'kng_tw_layout' => 'masonry', ], ] ); $this->end_controls_section(); } /** * Register filters controls. * * @return void */ protected function register_filter_controls(): void { $this->start_controls_section( 'kng_tw_filters_section', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Filters', 'king-addons'), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'kng_tw_enable_filters', [ 'label' => esc_html__('Enable Filters', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', ] ); $this->add_control( 'kng_tw_filters_position', [ 'label' => esc_html__('Filter Bar Position', 'king-addons'), 'type' => Controls_Manager::SELECT, 'options' => [ 'top' => esc_html__('Top', 'king-addons'), 'left' => esc_html__('Left', 'king-addons'), ], 'default' => 'top', 'condition' => [ 'kng_tw_enable_filters' => 'yes', ], ] ); $this->add_control( 'kng_tw_enable_category_filter', [ 'label' => esc_html__('Category Filter', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', 'condition' => [ 'kng_tw_enable_filters' => 'yes', ], ] ); $this->add_control( 'kng_tw_all_label', [ 'label' => esc_html__('All Label', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('All', 'king-addons'), 'condition' => [ 'kng_tw_enable_filters' => 'yes', ], ] ); $this->add_control( 'kng_tw_enable_rating_filter', [ 'label' => esc_html__('Rating Filter', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', 'condition' => [ 'kng_tw_enable_filters' => 'yes', ], ] ); $this->add_control( 'kng_tw_rating_ui', [ 'label' => esc_html__('Rating UI', 'king-addons'), 'type' => Controls_Manager::SELECT, 'options' => [ 'chips' => esc_html__('Chips', 'king-addons'), 'dropdown' => esc_html__('Dropdown', 'king-addons'), ], 'default' => 'chips', 'condition' => [ 'kng_tw_enable_filters' => 'yes', 'kng_tw_enable_rating_filter' => 'yes', ], ] ); $this->add_control( 'kng_tw_enable_search', [ 'label' => esc_html__('Search Field', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', 'condition' => [ 'kng_tw_enable_filters' => 'yes', ], ] ); $this->add_control( 'kng_tw_search_placeholder', [ 'label' => esc_html__('Search Placeholder', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('Search testimonials', 'king-addons'), 'condition' => [ 'kng_tw_enable_filters' => 'yes', 'kng_tw_enable_search' => 'yes', ], ] ); $this->add_control( 'kng_tw_filters_sticky', [ 'label' => sprintf(__('Sticky Filters %s', 'king-addons'), ''), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', 'condition' => [ 'kng_tw_enable_filters' => 'yes', ], 'classes' => 'king-addons-pro-control no-distance', ] ); $this->end_controls_section(); } /** * Register load more controls. * * @return void */ protected function register_load_more_controls(): void { $this->start_controls_section( 'kng_tw_load_more_section', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Load More', 'king-addons'), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'kng_tw_enable_load_more', [ 'label' => esc_html__('Enable Load More', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', ] ); $this->add_control( 'kng_tw_initial_items', [ 'label' => esc_html__('Initial Items', 'king-addons'), 'type' => Controls_Manager::NUMBER, 'min' => 6, 'max' => 24, 'step' => 1, 'default' => 9, 'condition' => [ 'kng_tw_enable_load_more' => 'yes', ], ] ); $this->add_control( 'kng_tw_items_per_load', [ 'label' => esc_html__('Items per Load', 'king-addons'), 'type' => Controls_Manager::NUMBER, 'min' => 4, 'max' => 20, 'step' => 1, 'default' => 6, 'condition' => [ 'kng_tw_enable_load_more' => 'yes', ], ] ); $this->add_control( 'kng_tw_load_more_text', [ 'label' => esc_html__('Load More Text', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('Load more', 'king-addons'), 'condition' => [ 'kng_tw_enable_load_more' => 'yes', ], ] ); $this->add_control( 'kng_tw_loading_text', [ 'label' => esc_html__('Loading Text', 'king-addons'), 'type' => Controls_Manager::TEXT, 'default' => esc_html__('Loading...', 'king-addons'), 'condition' => [ 'kng_tw_enable_load_more' => 'yes', ], ] ); $this->add_control( 'kng_tw_enable_skeleton', [ 'label' => esc_html__('Skeleton Loader', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', 'condition' => [ 'kng_tw_enable_load_more' => 'yes', ], ] ); $this->add_control( 'kng_tw_skeleton_count', [ 'label' => esc_html__('Skeleton Count', 'king-addons'), 'type' => Controls_Manager::NUMBER, 'min' => 1, 'max' => 12, 'step' => 1, 'default' => 3, 'condition' => [ 'kng_tw_enable_load_more' => 'yes', 'kng_tw_enable_skeleton' => 'yes', ], ] ); $this->add_control( 'kng_tw_infinite_scroll', [ 'label' => sprintf(__('Infinite Scroll %s', 'king-addons'), ''), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', 'condition' => [ 'kng_tw_enable_load_more' => 'yes', ], 'classes' => 'king-addons-pro-control no-distance', ] ); $this->end_controls_section(); } /** * Register empty state controls. * * @return void */ protected function register_empty_state_controls(): void { $this->start_controls_section( 'kng_tw_empty_section', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Empty State', 'king-addons'), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'kng_tw_enable_empty_state', [ 'label' => esc_html__('Show Empty Message', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', ] ); $this->add_control( 'kng_tw_empty_text', [ 'label' => esc_html__('Empty Message', 'king-addons'), 'type' => Controls_Manager::TEXTAREA, 'default' => esc_html__('No testimonials match your filters.', 'king-addons'), 'condition' => [ 'kng_tw_enable_empty_state' => 'yes', ], ] ); $this->end_controls_section(); } /** * Register editor preview controls. * * @return void */ protected function register_editor_controls(): void { $this->start_controls_section( 'kng_tw_editor_section', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Editor Preview', 'king-addons'), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'kng_tw_editor_notice', [ 'type' => Controls_Manager::RAW_HTML, 'raw' => '
' . esc_html__('Editor note', 'king-addons') . ' ' . esc_html__('Live filtering and load more are optimized for the frontend. Use preview toggles if needed while editing.', 'king-addons') . '
', ] ); $this->add_control( 'kng_tw_editor_masonry_preview', [ 'label' => esc_html__('Enable Masonry Preview', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', ] ); $this->add_control( 'kng_tw_editor_load_more_preview', [ 'label' => esc_html__('Enable Load More Preview', 'king-addons'), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', ] ); $this->add_control( 'kng_tw_editor_max_items', [ 'label' => esc_html__('Max Items in Editor', 'king-addons'), 'type' => Controls_Manager::NUMBER, 'min' => 4, 'max' => 20, 'step' => 1, 'default' => 8, ] ); $this->end_controls_section(); } /** * Register style controls. * * @return void */ protected function register_style_controls(): void { $this->register_style_wall_controls(); $this->register_style_card_controls(); $this->register_style_typography_controls(); $this->register_style_avatar_controls(); $this->register_style_rating_controls(); $this->register_style_filter_controls(); $this->register_style_read_more_controls(); $this->register_style_load_more_controls(); $this->register_style_empty_state_controls(); $this->register_style_skeleton_controls(); } /** * Wall style controls. * * @return void */ protected function register_style_wall_controls(): void { $this->start_controls_section( 'kng_tw_style_wall', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Wall', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_group_control( Group_Control_Background::get_type(), [ 'name' => 'kng_tw_wall_bg', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall', ] ); $this->add_responsive_control( 'kng_tw_wall_padding', [ 'label' => esc_html__('Padding', 'king-addons'), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => ['px', 'em', 'rem'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->add_responsive_control( 'kng_tw_wall_max_width', [ 'label' => esc_html__('Content Width', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', '%'], 'range' => [ 'px' => ['min' => 320, 'max' => 1600], '%' => ['min' => 50, 'max' => 100], ], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-max-width: {{SIZE}}{{UNIT}};', ], ] ); $this->add_control( 'kng_tw_text_color', [ 'label' => esc_html__('Text Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-text-color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_muted_color', [ 'label' => esc_html__('Muted Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-muted-color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_border_color', [ 'label' => esc_html__('Border Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-border-color: {{VALUE}};', ], ] ); $this->end_controls_section(); } /** * Card style controls. * * @return void */ protected function register_style_card_controls(): void { $this->start_controls_section( 'kng_tw_style_card', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Card', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_control( 'kng_tw_card_bg', [ 'label' => esc_html__('Background', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__card' => 'background-color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => 'kng_tw_card_border', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__card', ] ); $this->add_responsive_control( 'kng_tw_card_radius', [ 'label' => esc_html__('Border Radius', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', '%'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__card' => 'border-radius: {{SIZE}}{{UNIT}};', ], ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => 'kng_tw_card_shadow', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__card', ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => 'kng_tw_card_shadow_hover', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__card:hover', ] ); $this->add_responsive_control( 'kng_tw_card_hover_translate', [ 'label' => esc_html__('Hover Lift', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px'], 'range' => [ 'px' => ['min' => 0, 'max' => 20], ], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-card-hover-translate: {{SIZE}}{{UNIT}};', ], ] ); $this->add_control( 'kng_tw_card_hover_duration', [ 'label' => esc_html__('Hover Transition (s)', 'king-addons'), 'type' => Controls_Manager::NUMBER, 'min' => 0, 'max' => 2, 'step' => 0.05, 'default' => 0.2, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-card-hover-duration: {{VALUE}}s;', ], ] ); $this->add_responsive_control( 'kng_tw_card_padding', [ 'label' => esc_html__('Padding', 'king-addons'), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => ['px', 'em', 'rem'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__card' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->end_controls_section(); } /** * Typography style controls. * * @return void */ protected function register_style_typography_controls(): void { $this->start_controls_section( 'kng_tw_style_typography', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Typography', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_name_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__name', ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_meta_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__meta', ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_text_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__text', ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_source_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__source', ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_date_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__date', ] ); $this->end_controls_section(); } /** * Avatar style controls. * * @return void */ protected function register_style_avatar_controls(): void { $this->start_controls_section( 'kng_tw_style_avatar', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Avatar', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_responsive_control( 'kng_tw_avatar_box_size', [ 'label' => esc_html__('Size', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', 'em', 'rem'], 'range' => [ 'px' => ['min' => 24, 'max' => 120], 'em' => ['min' => 2, 'max' => 8], 'rem' => ['min' => 2, 'max' => 8], ], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__avatar' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', ], ] ); $this->add_responsive_control( 'kng_tw_avatar_radius', [ 'label' => esc_html__('Border Radius', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', '%'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__avatar' => 'border-radius: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .king-addons-testimonials-wall__avatar img' => 'border-radius: {{SIZE}}{{UNIT}};', ], ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => 'kng_tw_avatar_border', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__avatar', ] ); $this->end_controls_section(); } /** * Rating style controls. * * @return void */ protected function register_style_rating_controls(): void { $this->start_controls_section( 'kng_tw_style_rating', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Rating', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_responsive_control( 'kng_tw_star_size', [ 'label' => esc_html__('Star Size', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', 'em', 'rem'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-star-size: {{SIZE}}{{UNIT}};', ], ] ); $this->add_control( 'kng_tw_star_color', [ 'label' => esc_html__('Star Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-star-color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_star_empty_color', [ 'label' => esc_html__('Empty Star Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-star-muted: {{VALUE}};', ], ] ); $this->add_responsive_control( 'kng_tw_star_gap', [ 'label' => esc_html__('Star Gap', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', 'em', 'rem'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-star-gap: {{SIZE}}{{UNIT}};', ], ] ); $this->end_controls_section(); } /** * Filters style controls. * * @return void */ protected function register_style_filter_controls(): void { $this->start_controls_section( 'kng_tw_style_filters', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Filters', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_control( 'kng_tw_chip_style', [ 'label' => esc_html__('Chip Style', 'king-addons'), 'type' => Controls_Manager::SELECT, 'options' => [ 'filled' => esc_html__('Filled', 'king-addons'), 'outline' => esc_html__('Outline', 'king-addons'), ], 'default' => 'filled', ] ); $this->add_control( 'kng_tw_filters_alignment', [ 'label' => esc_html__('Filters Alignment', 'king-addons'), 'type' => Controls_Manager::SELECT, 'options' => [ 'flex-start' => esc_html__('Left', 'king-addons'), 'center' => esc_html__('Center', 'king-addons'), 'flex-end' => esc_html__('Right', 'king-addons'), 'space-between' => esc_html__('Space Between', 'king-addons'), ], 'default' => 'flex-start', 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__filters' => 'justify-content: {{VALUE}};', ], ] ); $this->add_responsive_control( 'kng_tw_filters_gap', [ 'label' => esc_html__('Filter Bar Gap', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', 'em', 'rem'], 'range' => [ 'px' => ['min' => 0, 'max' => 40], 'em' => ['min' => 0, 'max' => 3], 'rem' => ['min' => 0, 'max' => 3], ], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-filters-gap: {{SIZE}}{{UNIT}};', ], ] ); $this->add_responsive_control( 'kng_tw_filter_group_gap', [ 'label' => esc_html__('Filter Group Gap', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', 'em', 'rem'], 'range' => [ 'px' => ['min' => 0, 'max' => 30], 'em' => ['min' => 0, 'max' => 2], 'rem' => ['min' => 0, 'max' => 2], ], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-filter-group-gap: {{SIZE}}{{UNIT}};', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_chip_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__filter-chip', ] ); $this->add_control( 'kng_tw_chip_text_color', [ 'label' => esc_html__('Chip Text Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-chip-text: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_chip_bg_color', [ 'label' => esc_html__('Chip Background', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-chip-bg: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_chip_border_color', [ 'label' => esc_html__('Chip Border', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-chip-border: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_chip_active_text_color', [ 'label' => esc_html__('Active Text', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-chip-active-text: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_chip_active_bg_color', [ 'label' => esc_html__('Active Background', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-chip-active-bg: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_chip_active_border_color', [ 'label' => esc_html__('Active Border', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-chip-active-border: {{VALUE}};', ], ] ); $this->add_responsive_control( 'kng_tw_chip_radius', [ 'label' => esc_html__('Chip Radius', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', '%'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__filter-chip' => 'border-radius: {{SIZE}}{{UNIT}};', ], ] ); $this->add_responsive_control( 'kng_tw_chip_padding', [ 'label' => esc_html__('Chip Padding', 'king-addons'), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => ['px', 'em', 'rem'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__filter-chip' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_search_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__search-input', ] ); $this->add_responsive_control( 'kng_tw_search_padding', [ 'label' => esc_html__('Search Padding', 'king-addons'), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => ['px', 'em', 'rem'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__search-input' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->add_control( 'kng_tw_search_bg', [ 'label' => esc_html__('Search Background', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__search-input' => 'background-color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_search_text', [ 'label' => esc_html__('Search Text Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__search-input' => 'color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_search_border', [ 'label' => esc_html__('Search Border Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__search-input' => 'border-color: {{VALUE}};', ], ] ); $this->add_responsive_control( 'kng_tw_search_radius', [ 'label' => esc_html__('Search Radius', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', '%'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__search-input' => 'border-radius: {{SIZE}}{{UNIT}};', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_dropdown_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__rating-select', ] ); $this->add_responsive_control( 'kng_tw_dropdown_padding', [ 'label' => esc_html__('Dropdown Padding', 'king-addons'), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => ['px', 'em', 'rem'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__rating-select' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->add_control( 'kng_tw_dropdown_bg', [ 'label' => esc_html__('Dropdown Background', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__rating-select' => 'background-color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_dropdown_text', [ 'label' => esc_html__('Dropdown Text Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__rating-select' => 'color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_dropdown_border', [ 'label' => esc_html__('Dropdown Border', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__rating-select' => 'border-color: {{VALUE}};', ], ] ); $this->add_responsive_control( 'kng_tw_dropdown_radius', [ 'label' => esc_html__('Dropdown Radius', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', '%'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__rating-select' => 'border-radius: {{SIZE}}{{UNIT}};', ], ] ); $this->end_controls_section(); } /** * Read more style controls. * * @return void */ protected function register_style_read_more_controls(): void { $this->start_controls_section( 'kng_tw_style_read_more', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Read More', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_read_more_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__read-more', ] ); $this->start_controls_tabs('kng_tw_read_more_tabs'); $this->start_controls_tab( 'kng_tw_read_more_tab_normal', [ 'label' => esc_html__('Normal', 'king-addons'), ] ); $this->add_control( 'kng_tw_read_more_color', [ 'label' => esc_html__('Text Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__read-more' => 'color: {{VALUE}};', ], ] ); $this->end_controls_tab(); $this->start_controls_tab( 'kng_tw_read_more_tab_hover', [ 'label' => esc_html__('Hover', 'king-addons'), ] ); $this->add_control( 'kng_tw_read_more_color_hover', [ 'label' => esc_html__('Text Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__read-more:hover' => 'color: {{VALUE}};', ], ] ); $this->end_controls_tab(); $this->end_controls_tabs(); $this->add_responsive_control( 'kng_tw_read_more_spacing', [ 'label' => esc_html__('Spacing', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', 'em', 'rem'], 'range' => [ 'px' => ['min' => 0, 'max' => 30], 'em' => ['min' => 0, 'max' => 2], 'rem' => ['min' => 0, 'max' => 2], ], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__read-more' => 'margin-top: {{SIZE}}{{UNIT}};', ], ] ); $this->end_controls_section(); } /** * Load more button style controls. * * @return void */ protected function register_style_load_more_controls(): void { $this->start_controls_section( 'kng_tw_style_load_more', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Load More Button', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_load_more_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn', ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => 'kng_tw_load_more_border', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn', ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => 'kng_tw_load_more_shadow', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn', ] ); $this->start_controls_tabs('kng_tw_load_more_tabs'); $this->start_controls_tab( 'kng_tw_load_more_tab_normal', [ 'label' => esc_html__('Normal', 'king-addons'), ] ); $this->add_control( 'kng_tw_load_more_text_color', [ 'label' => esc_html__('Text Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn' => 'color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_load_more_bg', [ 'label' => esc_html__('Background Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn' => 'background-color: {{VALUE}};', ], ] ); $this->end_controls_tab(); $this->start_controls_tab( 'kng_tw_load_more_tab_hover', [ 'label' => esc_html__('Hover', 'king-addons'), ] ); $this->add_control( 'kng_tw_load_more_text_color_hover', [ 'label' => esc_html__('Text Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn:hover' => 'color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_load_more_bg_hover', [ 'label' => esc_html__('Background Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn:hover' => 'background-color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_load_more_border_hover', [ 'label' => esc_html__('Border Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn:hover' => 'border-color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => 'kng_tw_load_more_shadow_hover', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn:hover', ] ); $this->end_controls_tab(); $this->end_controls_tabs(); $this->add_responsive_control( 'kng_tw_load_more_padding', [ 'label' => esc_html__('Padding', 'king-addons'), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => ['px', 'em', 'rem'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->add_responsive_control( 'kng_tw_load_more_radius', [ 'label' => esc_html__('Border Radius', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', '%'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__load-more-btn' => 'border-radius: {{SIZE}}{{UNIT}};', ], ] ); $this->add_control( 'kng_tw_load_more_alignment', [ 'label' => esc_html__('Alignment', 'king-addons'), 'type' => Controls_Manager::SELECT, 'options' => [ 'flex-start' => esc_html__('Left', 'king-addons'), 'center' => esc_html__('Center', 'king-addons'), 'flex-end' => esc_html__('Right', 'king-addons'), ], 'default' => 'center', 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__load-more' => 'justify-content: {{VALUE}};', ], 'separator' => 'before', ] ); $this->end_controls_section(); } /** * Empty state style controls. * * @return void */ protected function register_style_empty_state_controls(): void { $this->start_controls_section( 'kng_tw_style_empty', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Empty State', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'kng_tw_empty_typography', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__empty', ] ); $this->add_control( 'kng_tw_empty_text_color', [ 'label' => esc_html__('Text Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__empty' => 'color: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_empty_bg', [ 'label' => esc_html__('Background Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__empty' => 'background-color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => 'kng_tw_empty_border', 'selector' => '{{WRAPPER}} .king-addons-testimonials-wall__empty', ] ); $this->add_responsive_control( 'kng_tw_empty_radius', [ 'label' => esc_html__('Border Radius', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', '%'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__empty' => 'border-radius: {{SIZE}}{{UNIT}};', ], ] ); $this->add_responsive_control( 'kng_tw_empty_padding', [ 'label' => esc_html__('Padding', 'king-addons'), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => ['px', 'em', 'rem'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__empty' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->add_control( 'kng_tw_empty_align', [ 'label' => esc_html__('Text Alignment', 'king-addons'), 'type' => Controls_Manager::SELECT, 'options' => [ 'left' => esc_html__('Left', 'king-addons'), 'center' => esc_html__('Center', 'king-addons'), 'right' => esc_html__('Right', 'king-addons'), ], 'default' => 'center', 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__empty' => 'text-align: {{VALUE}};', ], ] ); $this->end_controls_section(); } /** * Skeleton style controls. * * @return void */ protected function register_style_skeleton_controls(): void { $this->start_controls_section( 'kng_tw_style_skeleton', [ 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Skeleton Loader', 'king-addons'), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_control( 'kng_tw_skeleton_base', [ 'label' => esc_html__('Base Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-skeleton-base: {{VALUE}};', ], ] ); $this->add_control( 'kng_tw_skeleton_shine', [ 'label' => esc_html__('Shimmer Color', 'king-addons'), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall' => '--ka-tw-skeleton-shine: {{VALUE}};', ], ] ); $this->add_responsive_control( 'kng_tw_skeleton_radius', [ 'label' => esc_html__('Skeleton Radius', 'king-addons'), 'type' => Controls_Manager::SLIDER, 'size_units' => ['px', '%'], 'selectors' => [ '{{WRAPPER}} .king-addons-testimonials-wall__skeleton-card' => 'border-radius: {{SIZE}}{{UNIT}};', ], ] ); $this->end_controls_section(); } /** * Render widget output. * * @return void */ public function render(): void { $settings = $this->get_settings_for_display(); $items = $settings['kng_tw_items'] ?? []; if (empty($items)) { return; } $is_editor = $this->is_elementor_editor_context(); $max_editor_items = isset($settings['kng_tw_editor_max_items']) ? (int) $settings['kng_tw_editor_max_items'] : 8; if ($is_editor && $max_editor_items > 0) { $items = array_slice($items, 0, $max_editor_items); } $layout = $settings['kng_tw_layout'] ?? 'masonry'; $enable_filters = ($settings['kng_tw_enable_filters'] ?? 'yes') === 'yes'; $filters_position = $settings['kng_tw_filters_position'] ?? 'top'; $enable_category_filter = ($settings['kng_tw_enable_category_filter'] ?? 'yes') === 'yes'; $enable_rating_filter = ($settings['kng_tw_enable_rating_filter'] ?? 'yes') === 'yes'; $rating_ui = $settings['kng_tw_rating_ui'] ?? 'chips'; $enable_search = ($settings['kng_tw_enable_search'] ?? 'yes') === 'yes'; $search_placeholder = $settings['kng_tw_search_placeholder'] ?? esc_html__('Search testimonials', 'king-addons'); $enable_load_more = ($settings['kng_tw_enable_load_more'] ?? 'yes') === 'yes'; $editor_load_more_preview = ($settings['kng_tw_editor_load_more_preview'] ?? '') === 'yes'; $render_load_more = $enable_load_more && (!$is_editor || $editor_load_more_preview); $initial_items = isset($settings['kng_tw_initial_items']) ? (int) $settings['kng_tw_initial_items'] : 9; $items_per_load = isset($settings['kng_tw_items_per_load']) ? (int) $settings['kng_tw_items_per_load'] : 6; $initial_items = max(1, $initial_items); $items_per_load = max(1, $items_per_load); if (!$render_load_more) { $initial_items = count($items); } $load_more_text = $settings['kng_tw_load_more_text'] ?? esc_html__('Load more', 'king-addons'); $loading_text = $settings['kng_tw_loading_text'] ?? esc_html__('Loading...', 'king-addons'); $enable_skeleton = ($settings['kng_tw_enable_skeleton'] ?? 'yes') === 'yes'; $skeleton_count = isset($settings['kng_tw_skeleton_count']) ? (int) $settings['kng_tw_skeleton_count'] : 3; $skeleton_count = max(1, $skeleton_count); $enable_read_more = ($settings['kng_tw_enable_read_more'] ?? '') === 'yes'; $read_more_lines = isset($settings['kng_tw_read_more_lines']) ? (int) $settings['kng_tw_read_more_lines'] : 4; $read_more_text = $settings['kng_tw_read_more_text'] ?? esc_html__('Read more', 'king-addons'); $read_less_text = $settings['kng_tw_read_less_text'] ?? esc_html__('Read less', 'king-addons'); $enable_empty_state = ($settings['kng_tw_enable_empty_state'] ?? 'yes') === 'yes'; $empty_text = $settings['kng_tw_empty_text'] ?? esc_html__('No testimonials match your filters.', 'king-addons'); $show_avatar = ($settings['kng_tw_show_avatar'] ?? 'yes') === 'yes'; $show_meta = ($settings['kng_tw_show_meta'] ?? 'yes') === 'yes'; $show_rating = ($settings['kng_tw_show_rating'] ?? 'yes') === 'yes'; $show_date = ($settings['kng_tw_show_date'] ?? '') === 'yes'; $show_source = ($settings['kng_tw_show_source'] ?? 'yes') === 'yes'; $category_map = []; $item_categories = []; $has_rating = false; foreach ($items as $index => $item) { $raw_categories = is_string($item['kng_tw_categories'] ?? '') ? $item['kng_tw_categories'] : ''; $normalized = $this->normalize_categories($raw_categories); $item_categories[$index] = array_keys($normalized); foreach ($normalized as $slug => $label) { if (!isset($category_map[$slug])) { $category_map[$slug] = $label; } } $rating_value = $this->sanitize_rating($item['kng_tw_rating'] ?? 0); if ($rating_value > 0) { $has_rating = true; } } if (!$has_rating) { $enable_rating_filter = false; } $chip_style = $settings['kng_tw_chip_style'] ?? 'filled'; $editor_masonry_preview = ($settings['kng_tw_editor_masonry_preview'] ?? '') === 'yes'; $wrapper_classes = [ 'king-addons-testimonials-wall', 'king-addons-testimonials-wall--layout-' . sanitize_html_class((string) $layout), ]; if ($filters_position === 'left') { $wrapper_classes[] = 'king-addons-testimonials-wall--filters-left'; } if ($enable_read_more) { $wrapper_classes[] = 'king-addons-testimonials-wall--read-more'; } $wrapper_attributes = [ 'class' => implode(' ', $wrapper_classes), 'data-layout' => $layout, 'data-filters' => $enable_filters ? 'yes' : 'no', 'data-filter-position' => $filters_position, 'data-enable-category' => $enable_category_filter ? 'yes' : 'no', 'data-enable-rating' => $enable_rating_filter ? 'yes' : 'no', 'data-rating-ui' => $rating_ui, 'data-enable-search' => $enable_search ? 'yes' : 'no', 'data-enable-loadmore' => $render_load_more ? 'yes' : 'no', 'data-initial' => (string) $initial_items, 'data-per-load' => (string) $items_per_load, 'data-read-more' => $enable_read_more ? 'yes' : 'no', 'data-read-more-lines' => (string) max(2, $read_more_lines), 'data-read-more-text' => $read_more_text, 'data-read-less-text' => $read_less_text, 'data-chip-style' => $chip_style, 'data-editor-masonry' => $editor_masonry_preview ? 'yes' : 'no', 'data-editor-loadmore' => $editor_load_more_preview ? 'yes' : 'no', 'data-skeleton' => ($render_load_more && $enable_skeleton) ? 'yes' : 'no', 'data-skeleton-count' => (string) $skeleton_count, ]; $auto_cols = isset($settings['kng_tw_item_min_width']['size']) && (float) $settings['kng_tw_item_min_width']['size'] > 0; if ($auto_cols) { $wrapper_attributes['data-auto-cols'] = 'yes'; } $all_label = $settings['kng_tw_all_label'] ?? esc_html__('All', 'king-addons'); $date_format = get_option('date_format'); $filters_enabled = $enable_filters && ($enable_category_filter || $enable_rating_filter || $enable_search); ?>
render_attribute_string($wrapper_attributes); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
$label) : ?>
$item) : ?> sanitize_rating($item['kng_tw_rating'] ?? 0); $date = $item['kng_tw_date'] ?? ''; $meta_parts = array_filter([trim((string) $title), trim((string) $company)]); $meta = implode(' - ', $meta_parts); $item_classes = [ 'king-addons-testimonials-wall__item', ]; if (!empty($item['_id'])) { $item_classes[] = 'elementor-repeater-item-' . sanitize_html_class((string) $item['_id']); } if ($index < $initial_items) { $item_classes[] = 'is-visible'; } else { $item_classes[] = 'is-hidden'; } $categories_list = $item_categories[$index] ?? []; $data_categories = !empty($categories_list) ? implode(' ', array_map('sanitize_html_class', $categories_list)) : ''; $search_blob = implode(' ', array_filter([ $name, $title, $company, wp_strip_all_tags((string) $text), $source, implode(' ', $categories_list), ])); $item_attributes = [ 'class' => implode(' ', $item_classes), 'data-rating' => (string) $rating_value, 'data-categories' => $data_categories, 'data-search' => sanitize_text_field($search_blob), 'role' => 'listitem', ]; ?>
render_attribute_string($item_attributes); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
0) : ?>
label pairs. * * @param string $raw Raw category string. * * @return array */ protected function normalize_categories(string $raw): array { $labels = preg_split('/[,;]+/', $raw) ?: []; $normalized = []; foreach ($labels as $label) { $label = trim($label); if ($label === '') { continue; } $slug = sanitize_title($label); if ($slug === '') { continue; } if (!isset($normalized[$slug])) { $normalized[$slug] = $label; } } return $normalized; } /** * Sanitize rating value. * * @param mixed $value Raw rating value. * * @return int */ protected function sanitize_rating($value): int { $rating = is_numeric($value) ? (int) $value : 0; return max(0, min(5, $rating)); } /** * Render HTML attributes from array. * * @param array $attributes Attributes list. * * @return string */ protected function render_attribute_string(array $attributes): string { $pairs = []; foreach ($attributes as $key => $value) { if ($value === '' || $value === null) { continue; } $pairs[] = sprintf('%s="%s"', $key, esc_attr($value)); } return implode(' ', $pairs); } /** * Detect if Elementor editor/preview is active. * * @return bool */ protected function is_elementor_editor_context(): bool { if (isset($_GET['elementor-preview'])) { return true; } if (!defined('ELEMENTOR_VERSION') || !class_exists(Plugin::class)) { return false; } $plugin = Plugin::$instance; if (isset($plugin->editor) && is_object($plugin->editor) && method_exists($plugin->editor, 'is_edit_mode')) { if ($plugin->editor->is_edit_mode()) { return true; } } if (isset($plugin->preview) && is_object($plugin->preview) && method_exists($plugin->preview, 'is_preview_mode')) { if ($plugin->preview->is_preview_mode()) { return true; } } return false; } }