register_steps_section(); $this->register_fields_section(); $this->register_settings_section(); $this->register_integrations_section(); $this->register_style_form_section(); $this->register_style_fields_section(); $this->register_style_steps_section(); $this->register_style_button_section(); $this->register_style_messages_section(); } // ========================================================================= // Content Controls // ========================================================================= private function register_steps_section(): void { $this->start_controls_section( 'section_steps', [ 'label' => __( 'Steps', 'admore-widgets-suite' ), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'enable_multistep', [ 'label' => __( 'Multi-Step Form', 'admore-widgets-suite' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', ] ); $steps = new Repeater(); $steps->add_control( 'step_title', [ 'label' => __( 'Step Title', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'Step', 'admore-widgets-suite' ), ] ); $this->add_control( 'steps', [ 'type' => Controls_Manager::REPEATER, 'fields' => $steps->get_controls(), 'default' => [ [ 'step_title' => __( 'Contact Info', 'admore-widgets-suite' ) ], [ 'step_title' => __( 'Details', 'admore-widgets-suite' ) ], ], 'title_field' => '{{{ step_title }}}', 'condition' => [ 'enable_multistep' => 'yes' ], ] ); $this->end_controls_section(); } private function register_fields_section(): void { $this->start_controls_section( 'section_fields', [ 'label' => __( 'Fields', 'admore-widgets-suite' ), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $r = new Repeater(); $r->add_control( 'field_id', [ 'label' => __( 'Field ID', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => 'field_1', 'description' => __( 'Unique ID for conditional logic.', 'admore-widgets-suite' ), ] ); $r->add_control( 'field_type', [ 'label' => __( 'Type', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => 'text', 'options' => [ 'text' => __( 'Text', 'admore-widgets-suite' ), 'email' => __( 'Email', 'admore-widgets-suite' ), 'tel' => __( 'Phone', 'admore-widgets-suite' ), 'url' => __( 'URL', 'admore-widgets-suite' ), 'number' => __( 'Number', 'admore-widgets-suite' ), 'date' => __( 'Date', 'admore-widgets-suite' ), 'time' => __( 'Time', 'admore-widgets-suite' ), 'textarea' => __( 'Textarea', 'admore-widgets-suite' ), 'select' => __( 'Select', 'admore-widgets-suite' ), 'radio' => __( 'Radio', 'admore-widgets-suite' ), 'checkbox' => __( 'Checkbox', 'admore-widgets-suite' ), 'acceptance' => __( 'Acceptance (Terms / Privacy)', 'admore-widgets-suite' ), 'file' => __( 'File Upload', 'admore-widgets-suite' ), 'hidden' => __( 'Hidden', 'admore-widgets-suite' ), 'html' => __( 'HTML / Text', 'admore-widgets-suite' ), ], ] ); $r->add_control( 'field_label', [ 'label' => __( 'Label', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'Field Label', 'admore-widgets-suite' ), 'dynamic' => [ 'active' => true ], ] ); $r->add_control( 'placeholder', [ 'label' => __( 'Placeholder', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'dynamic' => [ 'active' => true ], 'description' => __( 'For a Select, this is the text of the empty first option.', 'admore-widgets-suite' ), 'condition' => [ 'field_type' => [ 'text', 'email', 'tel', 'url', 'number', 'textarea', 'select' ] ], ] ); $r->add_control( 'field_default', [ 'label' => __( 'Default Value', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'dynamic' => [ 'active' => true ], 'description' => __( 'Pre-filled value. For a Select or Radio, enter one of the options.', 'admore-widgets-suite' ), 'conditions' => [ 'relation' => 'or', 'terms' => [ [ 'name' => 'field_type', 'operator' => 'in', 'value' => [ 'text', 'email', 'tel', 'url', 'number', 'date', 'time', 'textarea', 'select', 'radio' ] ], [ 'relation' => 'and', 'terms' => [ [ 'name' => 'field_type', 'operator' => '===', 'value' => 'hidden' ], [ 'name' => 'hidden_source', 'operator' => '===', 'value' => 'static' ], ], ], ], ], ] ); // ── Hidden field ── $r->add_control( 'hidden_source', [ 'label' => __( 'Value From', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => 'static', 'options' => [ 'static' => __( 'Fixed value', 'admore-widgets-suite' ), 'url_param' => __( 'URL parameter (e.g. utm_source)', 'admore-widgets-suite' ), 'page_url' => __( 'Page URL', 'admore-widgets-suite' ), 'page_title' => __( 'Page title', 'admore-widgets-suite' ), 'referrer' => __( 'Referrer (previous page)', 'admore-widgets-suite' ), ], 'condition' => [ 'field_type' => 'hidden' ], ] ); $r->add_control( 'hidden_param', [ 'label' => __( 'Parameter Name', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'placeholder' => 'utm_source', 'condition' => [ 'field_type' => 'hidden', 'hidden_source' => 'url_param' ], ] ); // ── Date range ── $r->add_control( 'date_min', [ 'label' => __( 'Earliest Date', 'admore-widgets-suite' ), 'type' => Controls_Manager::DATE_TIME, 'picker_options' => [ 'enableTime' => false ], 'condition' => [ 'field_type' => 'date' ], ] ); $r->add_control( 'date_max', [ 'label' => __( 'Latest Date', 'admore-widgets-suite' ), 'type' => Controls_Manager::DATE_TIME, 'picker_options' => [ 'enableTime' => false ], 'condition' => [ 'field_type' => 'date' ], ] ); // ── Acceptance ── $r->add_control( 'acceptance_text', [ 'label' => __( 'Checkbox Text', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXTAREA, 'default' => __( 'I agree to the Privacy Policy.', 'admore-widgets-suite' ), 'description' => __( 'Links are allowed, e.g. <a href="/privacy-policy">Privacy Policy</a>.', 'admore-widgets-suite' ), 'condition' => [ 'field_type' => 'acceptance' ], ] ); // ── HTML / Text block ── $r->add_control( 'html_content', [ 'label' => __( 'Content', 'admore-widgets-suite' ), 'type' => Controls_Manager::WYSIWYG, 'default' => '

' . __( 'Section title', 'admore-widgets-suite' ) . '

', 'condition' => [ 'field_type' => 'html' ], ] ); $r->add_control( 'field_required', [ 'label' => __( 'Required', 'admore-widgets-suite' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'condition' => [ 'field_type!' => [ 'hidden', 'html' ] ], ] ); $r->add_control( 'field_options', [ 'label' => __( 'Options (one per line)', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXTAREA, 'default' => "Option 1\nOption 2\nOption 3", 'condition' => [ 'field_type' => [ 'select', 'radio', 'checkbox' ] ], ] ); $r->add_control( 'allowed_types', [ 'label' => __( 'Allowed Extensions', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => 'jpg,jpeg,png,pdf', 'condition' => [ 'field_type' => 'file' ], ] ); $r->add_control( 'step_index', [ 'label' => __( 'Step Index (0-based)', 'admore-widgets-suite' ), 'type' => Controls_Manager::NUMBER, 'default' => 0, 'min' => 0, ] ); $r->add_control( 'column_width', [ 'label' => __( 'Width', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => '100', 'options' => [ '100' => '100%', '50' => '50%', '33' => '33%', '25' => '25%' ], ] ); // Tablet / Mobile width overrides. Left on "Default", the field keeps the // automatic behaviour (33% / 25% become 50% on tablet, every field is full // width on mobile). The "(tablet)" / "(mobile)" selector prefixes make // Elementor wrap the rule in its own breakpoint media query. $width_options = [ '' => __( 'Default', 'admore-widgets-suite' ), '100' => '100%', '75' => '75%', '66' => '66%', '50' => '50%', '33' => '33%', '25' => '25%', ]; $width_css = 'flex-basis: calc({{VALUE}}% - var(--eppro-form-gap) * (1 - {{VALUE}} / 100)); max-width: calc({{VALUE}}% - var(--eppro-form-gap) * (1 - {{VALUE}} / 100));'; $r->add_control( 'column_width_tablet', [ 'label' => __( 'Width (Tablet)', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => '', 'options' => $width_options, 'selectors' => [ '(tablet){{WRAPPER}} .eppro-form-grid > {{CURRENT_ITEM}}' => $width_css ], ] ); $r->add_control( 'column_width_mobile', [ 'label' => __( 'Width (Mobile)', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => '', 'options' => $width_options, 'selectors' => [ '(mobile){{WRAPPER}} .eppro-form-grid > {{CURRENT_ITEM}}' => $width_css ], ] ); $r->add_control( 'field_icon', [ 'label' => __( 'Field Icon', 'admore-widgets-suite' ), 'type' => Controls_Manager::ICONS, 'separator' => 'before', 'condition' => [ 'field_type' => [ 'text', 'email', 'tel', 'url', 'number', 'textarea' ] ], ] ); $r->add_control( 'field_icon_position', [ 'label' => __( 'Icon Position', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => 'prefix', 'options' => [ 'prefix' => __( 'Prefix (Left)', 'admore-widgets-suite' ), 'suffix' => __( 'Suffix (Right)', 'admore-widgets-suite' ), ], 'condition' => [ 'field_type' => [ 'text', 'email', 'tel', 'url', 'number', 'textarea' ] ], ] ); // Conditional logic $r->add_control( 'condition_heading', [ 'label' => __( 'Conditional Logic', 'admore-widgets-suite' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before', ] ); $r->add_control( 'condition_enabled', [ 'label' => __( 'Enable', 'admore-widgets-suite' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', ] ); $r->add_control( 'condition_field', [ 'label' => __( 'Watch Field ID', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'condition' => [ 'condition_enabled' => 'yes' ], ] ); $r->add_control( 'condition_operator', [ 'label' => __( 'Operator', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => 'equals', 'options' => [ 'equals' => __( '= Equals', 'admore-widgets-suite' ), 'not_equals' => __( '≠ Not Equals', 'admore-widgets-suite' ), 'contains' => __( '⊃ Contains', 'admore-widgets-suite' ), 'not_contains' => __( '⊅ Not Contains', 'admore-widgets-suite' ), 'starts_with' => __( '↦ Starts With', 'admore-widgets-suite' ), 'ends_with' => __( '↤ Ends With', 'admore-widgets-suite' ), 'is_empty' => __( '○ Is Empty', 'admore-widgets-suite' ), 'not_empty' => __( '● Is Not Empty', 'admore-widgets-suite' ), ], 'condition' => [ 'condition_enabled' => 'yes' ], ] ); $r->add_control( 'condition_value', [ 'label' => __( 'Value', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'condition' => [ 'condition_enabled' => 'yes', 'condition_operator' => [ 'equals', 'not_equals', 'contains', 'not_contains', 'starts_with', 'ends_with' ], ], ] ); $this->add_control( 'form_fields', [ 'type' => Controls_Manager::REPEATER, 'fields' => $r->get_controls(), 'default' => [ [ 'field_id' => 'name', 'field_type' => 'text', 'field_label' => __( 'Full Name', 'admore-widgets-suite' ), 'placeholder' => __( 'Enter your full name', 'admore-widgets-suite' ), 'field_required' => 'yes' ], [ 'field_id' => 'email', 'field_type' => 'email', 'field_label' => __( 'Email Address', 'admore-widgets-suite' ), 'placeholder' => __( 'Enter your email address', 'admore-widgets-suite' ), 'field_required' => 'yes' ], [ 'field_id' => 'message', 'field_type' => 'textarea', 'field_label' => __( 'Message', 'admore-widgets-suite' ), 'placeholder' => __( 'Write your message here…', 'admore-widgets-suite' ), 'field_required' => 'yes' ], ], 'title_field' => '<# var t=field_label||field_id; #>{{{ t }}} ({{{ field_type }}})', ] ); $this->end_controls_section(); } private function register_settings_section(): void { $this->start_controls_section( 'section_settings', [ 'label' => __( 'Settings', 'admore-widgets-suite' ), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'form_name', [ 'label' => __( 'Form Name', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'Contact Form', 'admore-widgets-suite' ), 'description' => __( 'Used to identify submissions in Form Entries.', 'admore-widgets-suite' ), 'separator' => 'after', ] ); $this->add_control( 'submit_text', [ 'label' => __( 'Submit Text', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'Send Message', 'admore-widgets-suite' ) ] ); $this->add_control( 'submit_icon', [ 'label' => __( 'Submit Button Icon', 'admore-widgets-suite' ), 'type' => Controls_Manager::ICONS, ] ); $this->add_control( 'submit_icon_position', [ 'label' => __( 'Icon Position', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => 'after', 'options' => [ 'before' => __( 'Before Text', 'admore-widgets-suite' ), 'after' => __( 'After Text', 'admore-widgets-suite' ) ], 'condition' => [ 'submit_icon[value]!' => '' ], ] ); $this->add_control( 'next_text', [ 'label' => __( 'Next Text', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'Next', 'admore-widgets-suite' ), 'condition' => [ 'enable_multistep' => 'yes' ], 'separator' => 'before' ] ); $this->add_control( 'prev_text', [ 'label' => __( 'Previous Text', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'Back', 'admore-widgets-suite' ), 'condition' => [ 'enable_multistep' => 'yes' ] ] ); $this->add_control( 'email_to', [ 'label' => __( 'Send Email To', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => self::default_notify_email(), 'placeholder' => __( 'you@example.com', 'admore-widgets-suite' ), 'description' => __( 'Separate multiple addresses with commas. Leave empty to turn off email notifications.', 'admore-widgets-suite' ), 'separator' => 'before', ] ); $this->add_control( 'email_subject', [ 'label' => __( 'Email Subject', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'New Form Submission', 'admore-widgets-suite' ) ] ); $this->add_control( 'webhook_url', [ 'label' => __( 'Webhook URL', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'placeholder' => 'https://hooks.example.com/...', 'description' => __( 'Each submission is sent here as JSON. Stored on the server only — never shown to visitors.', 'admore-widgets-suite' ), ] ); $this->add_control( 'success_message', [ 'label' => __( 'Success Message', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXTAREA, 'default' => __( 'Thank you! Your message has been received.', 'admore-widgets-suite' ), 'separator' => 'before', ] ); $this->add_control( 'error_message', [ 'label' => __( 'Error Message', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXTAREA, 'default' => __( 'Something went wrong. Please try again.', 'admore-widgets-suite' ), ] ); $this->add_control( 'redirect_url', [ 'label' => __( 'Redirect After Submit', 'admore-widgets-suite' ), 'type' => Controls_Manager::URL, 'placeholder' => home_url( '/thank-you/' ), 'options' => false, 'dynamic' => [ 'active' => true ], 'description' => __( 'Optional. Visitors go to this page after a successful submission (e.g. a thank-you page for ad conversion tracking).', 'admore-widgets-suite' ), 'separator' => 'before', ] ); $this->add_control( 'redirect_delay', [ 'label' => __( 'Redirect Delay (seconds)', 'admore-widgets-suite' ), 'type' => Controls_Manager::NUMBER, 'min' => 0, 'max' => 10, 'default' => 1, 'condition' => [ 'redirect_url[url]!' => '' ], ] ); // ── CAPTCHA ─────────────────────────────────────────────────────────── $this->add_control( 'captcha_heading', [ 'label' => __( 'CAPTCHA', 'admore-widgets-suite' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before', ] ); $this->add_control( 'enable_captcha', [ 'label' => __( 'Enable CAPTCHA', 'admore-widgets-suite' ), 'type' => Controls_Manager::SWITCHER, 'default' => '', 'description' => __( 'Configure CAPTCHA type and API keys in Essential Pro Pack → Integrations settings first.', 'admore-widgets-suite' ), ] ); $this->end_controls_section(); } /** * Per-form integrations. API keys are set once in Essential Pro Pack → * Integrations; the submit handler runs EPPRO_Form_Integrations. */ private function register_integrations_section(): void { $this->start_controls_section( 'section_integrations', [ 'label' => __( 'Integrations', 'admore-widgets-suite' ), 'tab' => Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'integrations_note', [ 'type' => Controls_Manager::RAW_HTML, 'raw' => sprintf( /* translators: %s: link to the plugin's Integrations settings */ esc_html__( 'Add your Mailchimp / Brevo API keys in %s first.', 'admore-widgets-suite' ), '' . esc_html__( 'Essential Pro Pack → Integrations', 'admore-widgets-suite' ) . '' ), 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info', ] ); // ── Mailchimp ── $this->add_control( 'mc_enable', [ 'label' => __( 'Mailchimp', 'admore-widgets-suite' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'separator' => 'before', ] ); $this->add_control( 'mc_audience', [ 'label' => __( 'Audience ID', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'description' => __( 'Mailchimp → Audience → Settings → Audience name and defaults.', 'admore-widgets-suite' ), 'condition' => [ 'mc_enable' => 'yes' ], ] ); $this->add_control( 'mc_double_optin', [ 'label' => __( 'Double Opt-in', 'admore-widgets-suite' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', 'description' => __( 'New contacts confirm by e-mail before they are subscribed (recommended, required in many countries).', 'admore-widgets-suite' ), 'condition' => [ 'mc_enable' => 'yes' ], ] ); $this->add_control( 'mc_tags', [ 'label' => __( 'Tags', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'placeholder' => 'website, inquiry', 'condition' => [ 'mc_enable' => 'yes' ], ] ); // ── Brevo ── $this->add_control( 'brevo_enable', [ 'label' => __( 'Brevo (Sendinblue)', 'admore-widgets-suite' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'separator' => 'before', ] ); $this->add_control( 'brevo_list', [ 'label' => __( 'List ID', 'admore-widgets-suite' ), 'type' => Controls_Manager::NUMBER, 'min' => 1, 'description' => __( 'Brevo → Contacts → Lists (the number in the ID column). Phone numbers are sent only in +countrycode format.', 'admore-widgets-suite' ), 'condition' => [ 'brevo_enable' => 'yes' ], ] ); // ── Field mapping (Mailchimp + Brevo) — shown when either is on ── $mc_or_brevo = [ 'relation' => 'or', 'terms' => [ [ 'name' => 'mc_enable', 'operator' => '===', 'value' => 'yes' ], [ 'name' => 'brevo_enable', 'operator' => '===', 'value' => 'yes' ], ], ]; $this->add_control( 'map_heading', [ 'label' => __( 'Field Mapping (Field IDs)', 'admore-widgets-suite' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before', 'conditions' => $mc_or_brevo, ] ); $map = [ 'map_email' => [ __( 'Email Field ID', 'admore-widgets-suite' ), 'email', __( 'Empty = the first Email field.', 'admore-widgets-suite' ) ], 'map_name' => [ __( 'Full Name Field ID', 'admore-widgets-suite' ), 'name', __( 'Split into first / last name when the two fields below are empty.', 'admore-widgets-suite' ) ], 'map_first_name' => [ __( 'First Name Field ID', 'admore-widgets-suite' ), '', '' ], 'map_last_name' => [ __( 'Last Name Field ID', 'admore-widgets-suite' ), '', '' ], 'map_phone' => [ __( 'Phone Field ID', 'admore-widgets-suite' ), '', '' ], ]; foreach ( $map as $key => $info ) { $this->add_control( $key, [ 'label' => $info[0], 'type' => Controls_Manager::TEXT, 'default' => $info[1], 'description' => $info[2], 'label_block' => false, 'conditions' => $mc_or_brevo, ] ); } // ── Google Sheets ── $this->add_control( 'sheets_enable', [ 'label' => __( 'Google Sheets', 'admore-widgets-suite' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'separator' => 'before', ] ); $this->add_control( 'sheets_url', [ 'label' => __( 'Apps Script Web App URL', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'placeholder' => 'https://script.google.com/macros/s/…/exec', 'label_block' => true, 'description' => __( 'Setup steps and the script: Essential Pro Pack → Integrations → Google Sheets setup.', 'admore-widgets-suite' ), 'condition' => [ 'sheets_enable' => 'yes' ], ] ); // ── Slack / Discord ── $this->add_control( 'slack_enable', [ 'label' => __( 'Slack / Discord Notification', 'admore-widgets-suite' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'separator' => 'before', ] ); $this->add_control( 'slack_url', [ 'label' => __( 'Webhook URL', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'placeholder' => 'https://hooks.slack.com/services/…', 'label_block' => true, 'description' => __( 'A Slack incoming webhook or a Discord channel webhook.', 'admore-widgets-suite' ), 'condition' => [ 'slack_enable' => 'yes' ], ] ); $this->end_controls_section(); } // ========================================================================= // Style Controls // ========================================================================= private function register_style_form_section(): void { $this->start_controls_section( 'style_form', [ 'label' => __( 'Form', 'admore-widgets-suite' ), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_responsive_control( 'form_gap', [ 'label' => __( 'Field Gap', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'default' => [ 'size' => 16 ], 'selectors' => [ '{{WRAPPER}} .eppro-form-grid' => '--eppro-form-gap: {{SIZE}}{{UNIT}};' ], ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => 'form_shadow', 'selector' => '{{WRAPPER}} .eppro-form-wrap', ] ); $this->add_responsive_control( 'form_padding', [ 'label' => __( 'Padding', 'admore-widgets-suite' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', 'em' ], 'selectors' => [ '{{WRAPPER}} .eppro-form-wrap' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], ] ); $this->add_control( 'form_bg', [ 'label' => __( 'Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-form-wrap' => 'background-color: {{VALUE}};' ], ] ); $this->add_control( 'form_radius', [ 'label' => __( 'Border Radius', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-form-wrap' => 'border-radius: {{SIZE}}{{UNIT}};' ], ] ); $this->end_controls_section(); } private function register_style_fields_section(): void { $this->start_controls_section( 'style_fields', [ 'label' => __( 'Fields', 'admore-widgets-suite' ), 'tab' => Controls_Manager::TAB_STYLE, ] ); // ── Label ────────────────────────────────────────────────────────────── $this->add_control( 'label_position', [ 'label' => __( 'Label Position', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => 'top', 'options' => [ 'top' => __( 'Above Field', 'admore-widgets-suite' ), 'inline' => __( 'Inline (left)', 'admore-widgets-suite' ), 'hidden' => __( 'Hidden (placeholder only)', 'admore-widgets-suite' ), ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'label_typography', 'label' => __( 'Label Typography', 'admore-widgets-suite' ), 'selector' => '{{WRAPPER}} .eppro-field-label', ] ); $this->add_control( 'label_color', [ 'label' => __( 'Label Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-field-label' => 'color: {{VALUE}};' ], ] ); $this->add_responsive_control( 'label_spacing', [ 'label' => __( 'Label Bottom Spacing', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 0, 'max' => 30 ] ], 'selectors' => [ '{{WRAPPER}} .eppro-field-label' => 'margin-bottom: {{SIZE}}{{UNIT}};' ], 'condition' => [ 'label_position' => 'top' ], ] ); // ── Input fields ─────────────────────────────────────────────────────── $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'field_typography', 'selector' => '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select', 'separator' => 'before', ] ); $this->add_control( 'field_text_color', [ 'label' => __( 'Text Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select' => 'color: {{VALUE}};' ], ] ); $this->add_control( 'placeholder_color', [ 'label' => __( 'Placeholder Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-field input::placeholder' => 'color: {{VALUE}};', '{{WRAPPER}} .eppro-field textarea::placeholder' => 'color: {{VALUE}};', ], ] ); $this->add_control( 'field_bg', [ 'label' => __( 'Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#ffffff', 'selectors' => [ '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select' => 'background-color: {{VALUE}};' ], ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => 'field_border', 'selector' => '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select', ] ); $this->add_control( 'field_radius', [ 'label' => __( 'Border Radius', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select' => 'border-radius: {{SIZE}}{{UNIT}};' ], ] ); $this->add_responsive_control( 'field_padding', [ 'label' => __( 'Padding', 'admore-widgets-suite' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', 'em' ], 'selectors' => [ '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], ] ); // ── Field icon style ─────────────────────────────────────────────────── $this->add_control( 'field_icon_heading', [ 'label' => __( 'Field Icon', 'admore-widgets-suite' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before', ] ); $this->add_control( 'field_icon_color', [ 'label' => __( 'Icon Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#9ca3af', 'selectors' => [ '{{WRAPPER}} .eppro-field-icon i' => 'color: {{VALUE}};', '{{WRAPPER}} .eppro-field-icon svg' => 'fill: {{VALUE}};', ], ] ); $this->add_control( 'field_icon_size', [ 'label' => __( 'Icon Size (px)', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 10, 'max' => 36 ] ], 'default' => [ 'size' => 16 ], 'selectors' => [ '{{WRAPPER}} .eppro-field-icon i' => 'font-size: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .eppro-field-icon svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', ], ] ); // ── Focus state ──────────────────────────────────────────────────────── $this->add_control( 'field_focus_heading', [ 'label' => __( 'Focus State', 'admore-widgets-suite' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before', ] ); $this->add_control( 'field_focus_border_color', [ 'label' => __( 'Border Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => EPPRO_Elementor_Helper::brand_color(), 'selectors' => [ '{{WRAPPER}} .eppro-field input:focus' => 'border-color: {{VALUE}}; outline: none;', '{{WRAPPER}} .eppro-field textarea:focus' => 'border-color: {{VALUE}}; outline: none;', '{{WRAPPER}} .eppro-field select:focus' => 'border-color: {{VALUE}}; outline: none;', ], ] ); $this->add_control( 'field_focus_shadow', [ 'label' => __( 'Glow / Ring Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => EPPRO_Elementor_Helper::brand_color( 'primary', 0.15 ), 'selectors' => [ '{{WRAPPER}} .eppro-field input:focus' => 'box-shadow: 0 0 0 3px {{VALUE}};', '{{WRAPPER}} .eppro-field textarea:focus' => 'box-shadow: 0 0 0 3px {{VALUE}};', '{{WRAPPER}} .eppro-field select:focus' => 'box-shadow: 0 0 0 3px {{VALUE}};', ], ] ); $this->add_control( 'field_focus_bg', [ 'label' => __( 'Background on Focus', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-field input:focus' => 'background-color: {{VALUE}};', '{{WRAPPER}} .eppro-field textarea:focus' => 'background-color: {{VALUE}};', '{{WRAPPER}} .eppro-field select:focus' => 'background-color: {{VALUE}};', ], ] ); $this->add_control( 'field_error_heading', [ 'label' => __( 'Error / Invalid State', 'admore-widgets-suite' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before', ] ); $this->add_control( 'field_error_border_color', [ 'label' => __( 'Border Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#ef4444', 'selectors' => [ // The script marks invalid inputs with .eppro-has-error. '{{WRAPPER}} .eppro-field .eppro-input.eppro-has-error' => 'border-color: {{VALUE}};', ], ] ); $this->add_control( 'field_error_bg', [ 'label' => __( 'Background Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ // The script marks invalid inputs with .eppro-has-error. '{{WRAPPER}} .eppro-field .eppro-input.eppro-has-error' => 'background-color: {{VALUE}};', ], ] ); $this->add_control( 'field_error_msg_color', [ 'label' => __( 'Error Message Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#ef4444', 'selectors' => [ '{{WRAPPER}} .eppro-field-error' => 'color: {{VALUE}};' ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'field_error_typography', 'label' => __( 'Error Message Typography', 'admore-widgets-suite' ), 'selector' => '{{WRAPPER}} .eppro-field-error', ] ); $this->end_controls_section(); } /** * Multi-step progress indicator. Every colour is a CSS variable on the * indicator (see style.css); Completed falls back to the Active colours. */ private function register_style_steps_section(): void { $ind = '{{WRAPPER}} .eppro-step-indicator'; $this->start_controls_section( 'style_steps', [ 'label' => __( 'Step Indicator', 'admore-widgets-suite' ), 'tab' => Controls_Manager::TAB_STYLE, 'condition' => [ 'enable_multistep' => 'yes' ], ] ); $this->add_responsive_control( 'step_size', [ 'label' => __( 'Circle Size', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 16, 'max' => 80 ] ], 'selectors' => [ $ind => '--eppro-step-size: {{SIZE}}{{UNIT}};' ], ] ); $this->add_control( 'step_radius', [ 'label' => __( 'Circle Radius', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', '%' ], 'range' => [ 'px' => [ 'min' => 0, 'max' => 40 ], '%' => [ 'min' => 0, 'max' => 50 ] ], 'selectors' => [ $ind => '--eppro-step-radius: {{SIZE}}{{UNIT}};' ], ] ); $this->add_control( 'step_line', [ 'label' => __( 'Line Thickness', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 0, 'max' => 10 ] ], 'selectors' => [ $ind => '--eppro-step-line: {{SIZE}}{{UNIT}};' ], ] ); $this->add_control( 'step_shadow', [ 'label' => __( 'Circle Shadow', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => 'show', 'options' => [ 'show' => __( 'Show', 'admore-widgets-suite' ), 'hide' => __( 'Hide', 'admore-widgets-suite' ), ], 'selectors_dictionary' => [ 'show' => '', 'hide' => 'box-shadow: none;' ], 'selectors' => [ $ind . ' .eppro-step-dot .eppro-step-num' => '{{VALUE}}' ], ] ); $this->start_controls_tabs( 'step_color_tabs', [ 'separator' => 'before' ] ); // ── Normal (upcoming steps) ── $this->start_controls_tab( 'step_tab_normal', [ 'label' => __( 'Normal', 'admore-widgets-suite' ) ] ); $this->add_control( 'step_bg', [ 'label' => __( 'Circle Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-bg: {{VALUE}};' ], ] ); $this->add_control( 'step_color', [ 'label' => __( 'Number Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-color: {{VALUE}};' ], ] ); $this->add_control( 'step_label_color', [ 'label' => __( 'Label Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-label: {{VALUE}};' ], ] ); $this->add_control( 'step_line_color', [ 'label' => __( 'Line Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-line-color: {{VALUE}};' ], ] ); $this->end_controls_tab(); // ── Active (current step) ── $this->start_controls_tab( 'step_tab_active', [ 'label' => __( 'Active', 'admore-widgets-suite' ) ] ); $this->add_control( 'step_active_bg', [ 'label' => __( 'Circle Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-active-bg: {{VALUE}};' ], ] ); $this->add_control( 'step_active_color', [ 'label' => __( 'Number Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-active-color: {{VALUE}};' ], ] ); $this->add_control( 'step_active_label', [ 'label' => __( 'Label Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-active-label: {{VALUE}};' ], ] ); $this->end_controls_tab(); // ── Completed (previous steps) ── $this->start_controls_tab( 'step_tab_done', [ 'label' => __( 'Completed', 'admore-widgets-suite' ) ] ); $this->add_control( 'step_done_bg', [ 'label' => __( 'Circle Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'description' => __( 'Empty = same as Active.', 'admore-widgets-suite' ), 'selectors' => [ $ind => '--eppro-step-done-bg: {{VALUE}};' ], ] ); $this->add_control( 'step_done_color', [ 'label' => __( 'Number Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-done-color: {{VALUE}};' ], ] ); $this->add_control( 'step_done_label', [ 'label' => __( 'Label Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-done-label: {{VALUE}};' ], ] ); $this->add_control( 'step_line_done', [ 'label' => __( 'Progress Line Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ $ind => '--eppro-step-line-done: {{VALUE}};' ], ] ); $this->end_controls_tab(); $this->end_controls_tabs(); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'step_num_typography', 'label' => __( 'Number Typography', 'admore-widgets-suite' ), 'selector' => $ind . ' .eppro-step-num', 'separator' => 'before', ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'step_label_typography', 'label' => __( 'Label Typography', 'admore-widgets-suite' ), 'selector' => $ind . ' .eppro-step-label', ] ); $this->add_control( 'step_label_gap', [ 'label' => __( 'Label Spacing', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 0, 'max' => 30 ] ], 'selectors' => [ $ind => '--eppro-step-label-gap: {{SIZE}}{{UNIT}};' ], ] ); $this->add_responsive_control( 'step_spacing', [ 'label' => __( 'Space Below', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 0, 'max' => 80 ] ], 'selectors' => [ $ind => 'margin-bottom: {{SIZE}}{{UNIT}};' ], ] ); $this->end_controls_section(); } private function register_style_button_section(): void { $this->start_controls_section( 'style_button', [ 'label' => __( 'Buttons', 'admore-widgets-suite' ), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->start_controls_tabs( 'button_tabs' ); $this->start_controls_tab( 'btn_normal', [ 'label' => __( 'Normal', 'admore-widgets-suite' ) ] ); $this->add_control( 'btn_bg', [ 'label' => __( 'Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-form-btn' => 'background-color: {{VALUE}};' ] ] ); $this->add_control( 'btn_color', [ 'label' => __( 'Text Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#ffffff', 'selectors' => [ '{{WRAPPER}} .eppro-form-btn' => 'color: {{VALUE}};' ] ] ); $this->end_controls_tab(); $this->start_controls_tab( 'btn_hover', [ 'label' => __( 'Hover', 'admore-widgets-suite' ) ] ); $this->add_control( 'btn_bg_hover', [ 'label' => __( 'Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-form-btn:hover' => 'background-color: {{VALUE}};' ] ] ); $this->add_control( 'btn_color_hover', [ 'label' => __( 'Text Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-form-btn:hover' => 'color: {{VALUE}};' ] ] ); $this->end_controls_tab(); $this->end_controls_tabs(); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'btn_typography', 'selector' => '{{WRAPPER}} .eppro-form-btn', 'separator' => 'before', ] ); $this->add_responsive_control( 'btn_padding', [ 'label' => __( 'Padding', 'admore-widgets-suite' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', 'em' ], 'default' => [ 'top' => '12', 'right' => '28', 'bottom' => '12', 'left' => '28', 'unit' => 'px', 'isLinked' => false ], 'selectors' => [ '{{WRAPPER}} .eppro-form-btn' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], ] ); $this->add_control( 'btn_radius', [ 'label' => __( 'Border Radius', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'default' => [ 'size' => 6 ], 'selectors' => [ '{{WRAPPER}} .eppro-form-btn' => 'border-radius: {{SIZE}}{{UNIT}};' ], ] ); $this->add_control( 'btn_width', [ 'label' => __( 'Submit Button Width', 'admore-widgets-suite' ), 'type' => Controls_Manager::SELECT, 'default' => 'auto', 'options' => [ 'auto' => __( 'Auto', 'admore-widgets-suite' ), 'full' => __( 'Full Width', 'admore-widgets-suite' ), ], 'separator' => 'before', ] ); $this->add_responsive_control( 'btn_align', [ 'label' => __( 'Alignment', 'admore-widgets-suite' ), 'type' => Controls_Manager::CHOOSE, 'options' => [ 'flex-start' => [ 'title' => __( 'Left', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-left' ], 'center' => [ 'title' => __( 'Center', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-center' ], 'flex-end' => [ 'title' => __( 'Right', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-right' ], ], 'default' => 'flex-start', 'selectors' => [ '{{WRAPPER}} .eppro-form-actions' => 'justify-content: {{VALUE}};' ], 'condition' => [ 'btn_width' => 'auto' ], ] ); $this->end_controls_section(); } private function register_style_messages_section(): void { $this->start_controls_section( 'style_messages', [ 'label' => __( 'Success / Error Messages', 'admore-widgets-suite' ), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_control( 'success_msg_color', [ 'label' => __( 'Success Text Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#15803d', 'selectors' => [ '{{WRAPPER}} .eppro-form-success' => 'color: {{VALUE}};' ], ] ); $this->add_control( 'success_msg_bg', [ 'label' => __( 'Success Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#dcfce7', 'selectors' => [ '{{WRAPPER}} .eppro-form-success' => 'background-color: {{VALUE}};' ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'success_msg_typography', 'selector' => '{{WRAPPER}} .eppro-form-success', ] ); $this->add_control( 'error_msg_color', [ 'label' => __( 'Error Text Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#b91c1c', 'separator' => 'before', 'selectors' => [ '{{WRAPPER}} .eppro-form-error-global' => 'color: {{VALUE}};' ], ] ); $this->add_control( 'error_msg_bg', [ 'label' => __( 'Error Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#fee2e2', 'selectors' => [ '{{WRAPPER}} .eppro-form-error-global' => 'background-color: {{VALUE}};' ], ] ); $this->add_responsive_control( 'msg_padding', [ 'label' => __( 'Padding', 'admore-widgets-suite' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', 'em' ], 'default' => [ 'top' => '12', 'right' => '16', 'bottom' => '12', 'left' => '16', 'unit' => 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-form-success' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', '{{WRAPPER}} .eppro-form-error-global' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], 'separator' => 'before', ] ); $this->add_control( 'msg_border_radius', [ 'label' => __( 'Border Radius', 'admore-widgets-suite' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'default' => [ 'size' => 6 ], 'selectors' => [ '{{WRAPPER}} .eppro-form-success' => 'border-radius: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .eppro-form-error-global' => 'border-radius: {{SIZE}}{{UNIT}};', ], ] ); $this->end_controls_section(); } // ========================================================================= // Render // ========================================================================= /** Default recipient: the notification email chosen in the Setup Wizard (if any). */ private static function default_notify_email(): string { if ( ! class_exists( 'EPPRO_Admin_Settings' ) ) return ''; $settings = EPPRO_Admin_Settings::get_settings(); return sanitize_email( (string) ( $settings['wizard_notify_email'] ?? '' ) ); } protected function render(): void { $s = $this->get_settings_for_display(); $fields = EPPRO_Form_Handler::normalize_fields( (array) ( $s['form_fields'] ?? [] ) ); $multistep = ( $s['enable_multistep'] ?? '' ) === 'yes'; $steps = (array) ( $s['steps'] ?? [] ); $widget_id = $this->get_id(); if ( empty( $fields ) ) { if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) { echo '

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

' . esc_html__( 'Add fields in the Content tab → Form Fields.', 'admore-widgets-suite' ) . '

'; } return; } // The Elementor document that stores this widget (page, popup or template). // The submit handler loads the form configuration from it. $post_id = EPPRO_Elementor_Helper::current_document_id(); // Only non-sensitive values go to the browser. Recipients, webhook, // file rules and messages stay on the server. $config = [ 'widgetId' => $widget_id, 'postId' => $post_id, 'pageId' => (int) get_queried_object_id(), 'multistep' => $multistep, 'totalSteps' => $multistep ? max( 1, count( $steps ) ) : 1, 'errorMessage' => wp_kses_post( $s['error_message'] ?? '' ), 'i18n' => [ /* translators: %s: form field label */ 'required' => __( '%s is required.', 'admore-widgets-suite' ), 'invalidEmail' => __( 'Please enter a valid email address.', 'admore-widgets-suite' ), 'invalidPhone' => __( 'Please enter a valid phone number.', 'admore-widgets-suite' ), 'invalidUrl' => __( 'Please enter a valid URL.', 'admore-widgets-suite' ), 'acceptance' => __( 'Please accept to continue.', 'admore-widgets-suite' ), 'genericError' => __( 'Something went wrong. Please try again.', 'admore-widgets-suite' ), ], ]; $fields_config = []; foreach ( $fields as $def ) { $fields_config[] = [ 'id' => $def['id'], 'type' => $def['type'], 'label' => $def['label'], 'required' => $def['required'], ]; } $label_pos = $s['label_position'] ?? 'top'; $btn_width = $s['btn_width'] ?? 'auto'; ?>
$step ) : ?>
data-cond-field="" data-cond-op="" data-cond-val="" >
render_field( $def, $dom_id, $ph ); ?>
render_field( $def, $dom_id, $ph ); ?>
'; } elseif ( 'recaptcha_v3' === $captcha['type'] ) { wp_enqueue_script( 'google-recaptcha-v3', 'https://www.google.com/recaptcha/api.js?render=' . rawurlencode( $captcha['site_key'] ), [], '3.0', true ); $captcha_html = ''; } elseif ( 'hcaptcha' === $captcha['type'] ) { wp_enqueue_script( 'hcaptcha-api', 'https://js.hcaptcha.com/1/api.js', [], '1.0', true ); $captcha_html = '
'; } } $allowed_captcha = [ 'div' => [ 'class' => [], 'data-sitekey' => [] ], 'input' => [ 'type' => [], 'name' => [], 'class' => [], 'data-sitekey' => [] ], ]; echo wp_kses( $captcha_html, $allowed_captcha ); ?>
'; ?>
' . esc_textarea( $default ) . ''; break; case 'select': echo ''; break; case 'radio': case 'checkbox': $suffix = 'checkbox' === $ftype ? '[]' : ''; echo '
' . esc_html( $def['row']['field_label'] ?? '' ); if ( $required ) echo ''; echo '
'; foreach ( $def['options'] as $i => $opt ) { echo ''; } echo '
'; break; case 'acceptance': $text = (string) ( $def['row']['acceptance_text'] ?? '' ); if ( '' === trim( $text ) ) { $text = __( 'I agree to the Privacy Policy.', 'admore-widgets-suite' ); } $allowed = [ 'a' => [ 'href' => [], 'target' => [], 'rel' => [] ], 'strong' => [], 'em' => [], 'b' => [], 'i' => [], ]; echo ''; break; case 'hidden': // form.js fills in values that only the browser knows (URL parameter, // page URL / title, referrer); a fixed value is printed here. $source = $def['hidden_source']; echo ''; break; case 'html': echo '
' . wp_kses_post( (string) ( $def['row']['html_content'] ?? '' ) ) . '
'; break; case 'file': $accept = '.' . implode( ',.', $def['allowed_types'] ); echo ''; break; default: // text, email, tel, url, number, date, time echo ''; break; } } }