start_controls_section( 'section_items', [ 'label' => __( 'Timeline', 'admore-widgets-suite' ), ] ); $repeater = new \Elementor\Repeater(); $repeater->add_control( 'date', [ 'label' => __( 'Date / Label', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::TEXT, 'default' => __( 'January 2024', 'admore-widgets-suite' ), 'label_block' => true, 'dynamic' => [ 'active' => true ], ] ); $repeater->add_control( 'title', [ 'label' => __( 'Title', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::TEXT, 'default' => __( 'Milestone Title', 'admore-widgets-suite' ), 'label_block' => true, 'dynamic' => [ 'active' => true ], ] ); $repeater->add_control( 'description', [ 'label' => __( 'Description', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::WYSIWYG, 'default' => __( 'A brief description of this timeline event or milestone.', 'admore-widgets-suite' ), 'dynamic' => [ 'active' => true ], ] ); $repeater->add_control( 'icon', [ 'label' => __( 'Icon', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::ICONS, 'default' => [ 'value' => 'fas fa-circle', 'library' => 'fa-solid' ], ] ); $repeater->add_control( 'icon_color', [ 'label' => __( 'Icon Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, ] ); $repeater->add_control( 'icon_bg_color', [ 'label' => __( 'Icon Background', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, ] ); $repeater->add_control( 'link', [ 'label' => __( 'Link', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::URL, 'dynamic' => [ 'active' => true ], ] ); $this->add_control( 'items', [ 'label' => __( 'Items', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::REPEATER, 'fields' => $repeater->get_controls(), 'default' => [ [ 'date' => __( 'January 2022', 'admore-widgets-suite' ), 'title' => __( 'Company Founded', 'admore-widgets-suite' ), 'description' => __( 'Our journey began with a small team and a big vision.', 'admore-widgets-suite' ) ], [ 'date' => __( 'June 2022', 'admore-widgets-suite' ), 'title' => __( 'First Product Launch','admore-widgets-suite' ), 'description' => __( 'We launched our first product to an eager audience.', 'admore-widgets-suite' ) ], [ 'date' => __( 'March 2023', 'admore-widgets-suite' ), 'title' => __( '10K Customers', 'admore-widgets-suite' ), 'description' => __( 'Crossed the 10,000 customer milestone.', 'admore-widgets-suite' ) ], [ 'date' => __( 'Today', 'admore-widgets-suite' ), 'title' => __( 'Still Growing', 'admore-widgets-suite' ), 'description' => __( 'Continuing to innovate and expand every day.', 'admore-widgets-suite' ) ], ], 'title_field' => '{{{ date }}} — {{{ title }}}', ] ); $this->end_controls_section(); /* ── Layout ── */ $this->start_controls_section( 'section_layout', [ 'label' => __( 'Layout', 'admore-widgets-suite' ), ] ); $this->add_control( 'layout', [ 'label' => __( 'Layout', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => 'alternating', 'options' => [ 'left' => __( 'Cards on Left', 'admore-widgets-suite' ), 'right' => __( 'Cards on Right', 'admore-widgets-suite' ), 'alternating' => __( 'Alternating (Classic)', 'admore-widgets-suite' ), 'horizontal' => __( 'Horizontal', 'admore-widgets-suite' ), ], ] ); $this->add_control( 'animate', [ 'label' => __( 'Animate Items on Scroll', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'default' => 'yes', 'return_value' => 'yes', ] ); $this->add_responsive_control( 'item_spacing', [ 'label' => __( 'Item Spacing', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 0, 'max' => 100 ] ], 'default' => [ 'size' => 32, 'unit' => 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-item' => 'margin-bottom: {{SIZE}}{{UNIT}};' ], 'condition' => [ 'layout!' => 'horizontal' ], ] ); $this->add_control( 'show_connector', [ 'label' => __( 'Card Connector Arrow', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'default' => 'yes', 'return_value' => 'yes', 'separator' => 'before', 'condition' => [ 'layout!' => 'horizontal' ], ] ); $this->add_control( 'title_tag', [ 'label' => __( 'Title HTML Tag', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => 'h4', 'options' => [ 'h2' => 'H2', 'h3' => 'H3', 'h4' => 'H4', 'h5' => 'H5', 'h6' => 'H6', 'p' => 'P', ], ] ); $this->end_controls_section(); /* ── Style: Line ── */ $this->start_controls_section( 'section_style_line', [ 'label' => __( 'Line', 'admore-widgets-suite' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE, ] ); $this->add_control( 'line_color', [ 'label' => __( 'Line Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'default' => '#c4b5fd', 'selectors' => [ '{{WRAPPER}} .eppro-timeline--left::before' => 'background-color: {{VALUE}};', '{{WRAPPER}} .eppro-timeline--right::before' => 'background-color: {{VALUE}};', '{{WRAPPER}} .eppro-timeline--alternating::before' => 'background-color: {{VALUE}};', '{{WRAPPER}} .eppro-timeline-h-line' => 'background-color: {{VALUE}};', ], ] ); $this->add_responsive_control( 'line_width', [ 'label' => __( 'Line Width', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 1, 'max' => 8 ] ], 'default' => [ 'size' => 2, 'unit' => 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline--left::before' => 'width: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .eppro-timeline--right::before' => 'width: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .eppro-timeline--alternating::before' => 'width: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .eppro-timeline-h-line' => 'height: {{SIZE}}{{UNIT}};', ], ] ); $this->end_controls_section(); /* ── Style: Icon ── */ $this->start_controls_section( 'section_style_icon', [ 'label' => __( 'Icon / Dot', 'admore-widgets-suite' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE, ] ); $this->add_responsive_control( 'icon_size', [ 'label' => __( 'Icon Size', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 8, 'max' => 64 ] ], 'default' => [ 'size' => 16, 'unit' => 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-icon i' => 'font-size: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .eppro-timeline-icon svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', ], ] ); $this->add_responsive_control( 'icon_box_size', [ 'label' => __( 'Box Size', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 20, 'max' => 80 ] ], 'default' => [ 'size' => 36, 'unit' => 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-icon' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}}; min-width: {{SIZE}}{{UNIT}};', ], ] ); $this->add_control( 'icon_color', [ 'label' => __( 'Default Icon Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'default' => '#ffffff', 'selectors' => [ '{{WRAPPER}} .eppro-timeline-icon i' => 'color: {{VALUE}};', '{{WRAPPER}} .eppro-timeline-icon svg' => 'fill: {{VALUE}};', ], 'separator' => 'before', ] ); $this->add_control( 'icon_bg', [ 'label' => __( 'Default Background', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'default' => EPPRO_Elementor_Helper::brand_color(), 'selectors' => [ '{{WRAPPER}} .eppro-timeline-icon' => 'background-color: {{VALUE}};' ], ] ); $this->add_responsive_control( 'icon_border_radius', [ 'label' => __( 'Border Radius', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px', '%' ], 'default' => [ 'size' => 50, 'unit' => '%' ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-icon' => 'border-radius: {{SIZE}}{{UNIT}};' ], ] ); $this->add_group_control( \Elementor\Group_Control_Border::get_type(), [ 'name' => 'icon_border', 'selector' => '{{WRAPPER}} .eppro-timeline-icon', 'separator' => 'before', ] ); $this->end_controls_section(); /* ── Style: Card ── */ $this->start_controls_section( 'section_style_card', [ 'label' => __( 'Card', 'admore-widgets-suite' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE, ] ); $this->add_group_control( \Elementor\Group_Control_Background::get_type(), [ 'name' => 'card_bg', 'selector' => '{{WRAPPER}} .eppro-timeline-card', ] ); $this->add_group_control( \Elementor\Group_Control_Border::get_type(), [ 'name' => 'card_border', 'selector' => '{{WRAPPER}} .eppro-timeline-card', ] ); $this->add_responsive_control( 'card_border_radius', [ 'label' => __( 'Border Radius', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%' ], 'default' => [ 'top' => '8', 'right' => '8', 'bottom' => '8', 'left' => '8', 'unit' => 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-card' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], ] ); $this->add_responsive_control( 'card_padding', [ 'label' => __( 'Padding', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', 'em' ], 'default' => [ 'top' => '20', 'right' => '24', 'bottom' => '20', 'left' => '24', 'unit' => 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-card' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], ] ); $this->add_group_control( \Elementor\Group_Control_Box_Shadow::get_type(), [ 'name' => 'card_shadow', 'selector' => '{{WRAPPER}} .eppro-timeline-card', ] ); $this->add_control( 'card_hover_bg', [ 'label' => __( 'Hover Background', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'separator' => 'before', 'selectors' => [ '{{WRAPPER}} .eppro-timeline-card:hover' => 'background-color: {{VALUE}};' ], ] ); $this->add_group_control( \Elementor\Group_Control_Box_Shadow::get_type(), [ 'name' => 'card_hover_shadow', 'label' => __( 'Hover Box Shadow', 'admore-widgets-suite' ), 'selector' => '{{WRAPPER}} .eppro-timeline-card:hover', ] ); $this->add_control( 'connector_color', [ 'label' => __( 'Connector Arrow Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'default' => '#ffffff', 'separator' => 'before', 'selectors' => [ '{{WRAPPER}}' => '--eppro-tl-connector: {{VALUE}};' ], 'condition' => [ 'show_connector' => 'yes', 'layout!' => 'horizontal' ], ] ); $this->end_controls_section(); /* ── Style: Typography ── */ $this->start_controls_section( 'section_style_typo', [ 'label' => __( 'Typography', 'admore-widgets-suite' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE, ] ); $this->add_group_control( \Elementor\Group_Control_Typography::get_type(), [ 'name' => 'date_typography', 'label' => __( 'Date / Label', 'admore-widgets-suite' ), 'selector' => '{{WRAPPER}} .eppro-timeline-date', ] ); $this->add_control( 'date_color', [ 'label' => __( 'Date Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'default' => EPPRO_Elementor_Helper::brand_color(), 'selectors' => [ '{{WRAPPER}} .eppro-timeline-date' => 'color: {{VALUE}};' ], ] ); $this->add_group_control( \Elementor\Group_Control_Typography::get_type(), [ 'name' => 'title_typography', 'label' => __( 'Title', 'admore-widgets-suite' ), 'selector' => '{{WRAPPER}} .eppro-timeline-title', 'separator' => 'before', ] ); $this->add_control( 'title_color', [ 'label' => __( 'Title Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-timeline-title, {{WRAPPER}} .eppro-timeline-title a' => 'color: {{VALUE}};' ], ] ); $this->add_group_control( \Elementor\Group_Control_Typography::get_type(), [ 'name' => 'desc_typography', 'label' => __( 'Description', 'admore-widgets-suite' ), 'selector' => '{{WRAPPER}} .eppro-timeline-desc', 'separator' => 'before', ] ); $this->add_control( 'desc_color', [ 'label' => __( 'Description Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-timeline-desc' => 'color: {{VALUE}};' ], ] ); $this->add_control( 'desc_bg_color', [ 'label' => __( 'Description Background', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-timeline-desc' => 'background-color: {{VALUE}};' ], ] ); $this->add_responsive_control( 'desc_alignment', [ 'label' => __( 'Description Alignment', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::CHOOSE, 'options' => [ 'left' => [ 'title' => __( 'Left', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-left' ], 'center' => [ 'title' => __( 'Center', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-center' ], 'right' => [ 'title' => __( 'Right', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-right' ], ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-desc' => 'text-align: {{VALUE}};' ], 'separator' => 'before', ] ); $this->add_responsive_control( 'desc_max_width', [ 'label' => __( 'Max Width', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'range' => [ 'px' => [ 'min' => 50, 'max' => 800 ], '%' => [ 'min' => 10, 'max' => 100 ] ], 'size_units' => [ 'px', '%' ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-desc' => 'max-width: {{SIZE}}{{UNIT}};' ], ] ); $this->add_responsive_control( 'desc_padding', [ 'label' => __( 'Padding', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', 'em', '%' ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-desc' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], 'separator' => 'before', ] ); $this->add_control( 'desc_border_radius', [ 'label' => __( 'Border Radius', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'range' => [ 'px' => [ 'min' => 0, 'max' => 50 ] ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-desc' => 'border-radius: {{SIZE}}px;' ], ] ); $this->add_responsive_control( 'desc_spacing', [ 'label' => __( 'Top Spacing', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'range' => [ 'px' => [ 'min' => 0, 'max' => 40 ] ], 'selectors' => [ '{{WRAPPER}} .eppro-timeline-desc' => 'margin-top: {{SIZE}}px;' ], 'separator' => 'before', ] ); $this->end_controls_section(); $this->eppro_register_entrance_animation_controls(); } // ------------------------------------------------------------------------- // Render // ------------------------------------------------------------------------- protected function render(): void { $s = $this->get_settings_for_display(); $items = $s['items'] ?? []; $layout = $s['layout'] ?? 'left'; $animate = 'yes' === ( $s['animate'] ?? 'yes' ); $tag = in_array( $s['title_tag'] ?? 'h4', [ 'h2','h3','h4','h5','h6','p' ], true ) ? $s['title_tag'] : 'h4'; if ( empty( $items ) ) { if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) { echo '

' . esc_html__( 'Timeline', 'admore-widgets-suite' ) . '

' . esc_html__( 'Add timeline items in the Content tab.', 'admore-widgets-suite' ) . '

'; } return; } $wrap_class = 'eppro-timeline eppro-timeline--' . esc_attr( $layout ); $is_editor = \Elementor\Plugin::$instance->editor->is_edit_mode(); if ( $animate && ! $is_editor ) $wrap_class .= ' eppro-timeline--animate'; if ( 'yes' === ( $s['show_connector'] ?? 'yes' ) && 'horizontal' !== $layout ) $wrap_class .= ' eppro-timeline--connector'; $is_horizontal = 'horizontal' === $layout; ?>
$item ) : $date = $item['date'] ?? ''; $title = $item['title'] ?? ''; $desc = $item['description'] ?? ''; $icon = $item['icon'] ?? []; $icon_color = $item['icon_color'] ?? ''; $icon_bg = $item['icon_bg_color'] ?? ''; $link = $item['link'] ?? []; $link_url = $link['url'] ?? ''; $link_ext = ! empty( $link['is_external'] ); $icon_style = ''; if ( $icon_color ) $icon_style .= 'color:' . esc_attr( $icon_color ) . ';'; if ( $icon_bg ) $icon_style .= 'background-color:' . esc_attr( $icon_bg ) . ';'; $item_class = 'eppro-timeline-item'; if ( 'alternating' === $layout && 0 === $index % 2 ) { $item_class .= ' eppro-timeline-item--left'; } elseif ( 'alternating' === $layout ) { $item_class .= ' eppro-timeline-item--right'; } ?>
> 'true' ] ); endif; ?>
< class="eppro-timeline-title"> > >
> 'true' ] ); endif; ?>
< class="eppro-timeline-title"> > >