Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance: form fields promo popup and modals #1509

Open
wants to merge 76 commits into
base: develop
Choose a base branch
from

Conversation

sapayth
Copy link
Member

@sapayth sapayth commented Jan 29, 2025

fixes #660

Update the promotional pop-ups for the Pro version upgrade anywhere in the WPUF form builder interface (for example: premium icons).

Summary by CodeRabbit

  • New Features
    • Launched an updated form builder interface with dynamic panels and an integrated template selection modal for streamlined field management.
    • Introduced new fields for time and phone inputs, enhancing form capabilities.
  • Style & UX Enhancements
    • Refreshed visuals with modern SVG icons, refined dropdowns, drag-and-drop zones, and improved interactive feedback.
    • Added new CSS styles utilizing Tailwind CSS for consistent design across components.
  • Validation & Guidance Improvements
    • Enhanced error messaging and real-time validations (including reCAPTCHA prompts) to provide clearer user guidance.
    • Updated help texts and validation messages for better user clarity.

Enjoy a more responsive, intuitive, and visually cohesive form creation experience.

sapayth added 30 commits October 7, 2024 17:59
commit daae343
Author: Sapayth Hossain <[email protected]>
Date:   Fri Oct 25 10:21:05 2024 +0600

    fix logo, minor css

commit 7590512
Author: Sapayth Hossain <[email protected]>
Date:   Thu Oct 17 13:00:12 2024 +0600

    pro icon and link

commit b720564
Author: Sapayth Hossain <[email protected]>
Date:   Wed Oct 16 17:31:46 2024 +0600

    action buttons

commit 743860f
Author: Sapayth Hossain <[email protected]>
Date:   Wed Oct 16 13:10:14 2024 +0600

    various fields

    time, phone field, pro fields, image, file, recaptcha, hidden fields

commit e58e788
Merge: 2b12da4 f92a621
Author: Sapayth Hossain <[email protected]>
Date:   Tue Oct 15 17:25:44 2024 +0600

    Merge remote-tracking branch 'upstream/develop' into enhance/form_builder_content_body_ui_redesign

commit 2b12da4
Author: Sapayth Hossain <[email protected]>
Date:   Tue Oct 15 17:24:24 2024 +0600

    column field, section break

commit 63f6663
Author: Sapayth Hossain <[email protected]>
Date:   Mon Oct 14 21:47:26 2024 +0600

    regular fields
Copy link

coderabbitai bot commented Jan 29, 2025

Walkthrough

This pull request introduces a wide-ranging set of updates. A new Tailwind CSS configuration is integrated into the Grunt build process, and many Vue components in the admin form builder interface have been enhanced with additional mixins, computed properties, and refined templates. Several PHP classes and form templates have been updated with revised iconography, improved asset management, and conditional rendering changes. CSS/LESS files have been reorganized with new variables and style tweaks. Overall, the changes update tooling, interactivity, and visual presentation across the form builder module.

Changes

File(s) Changed Change Summary
Gruntfile.js Added Tailwind CSS integration with a new constant, watch target, and shell task command for Tailwind processing.
Lib/Appsero/Client.php Modified the get_plugin_data call by adding parameters to alter the returned plugin data format.
admin/form-builder/assets/js/components/... Introduced new Vue components (e.g. builder-stage-v4-1, form-fields-v4-1) and updated existing ones (field-checkbox, field-text, etc.) by adding mixins (form_field_mixin), improving methods, computed properties, and template structures for enhanced UI interactions.
admin/form-builder/assets/js/mixins/... & assets/js/wpuf-form-builder-mixins.js Added new methods (builder_class_names, is_pro_preview, action_button_classes) and updated default prop values for a more robust mixin behavior.
assets/css/... & admin/form-builder/assets/less/... Updated color variables and styles (e.g. tailwind variable @wpufPrimary, dropzone background/border, modal layouts) to enhance visual consistency.
includes/... (various PHP files) Updated form builder view integration, asset enqueueing, modal templates, and icon assignments in form field classes; also removed the numeric field class.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant GWatch as Grunt Watch
    participant TTask as Tailwind Task
    participant Shell as Shell Task
    participant CLI as Tailwind CLI

    Dev->>GWatch: Save changes in CSS/PHP files
    GWatch->>TTask: Detect changes in Tailwind files
    TTask->>Shell: Execute Tailwind command
    Shell->>CLI: Run Tailwind processing
    CLI-->>Shell: Process CSS output
    Shell-->>TTask: Command complete
    TTask-->>GWatch: Task finished
Loading
sequenceDiagram
    participant User as Form Builder User
    participant VueC as Vue Component (form-fields-v4-1)
    participant Store as Vuex Store
    participant Preview as Form Preview Stage

    User->>VueC: Drag and drop field from sidebar
    VueC->>Store: Commit field addition/update
    Store-->>VueC: Return updated state
    VueC->>Preview: Render new form field display
    Preview-->>User: Updated interactive form view
Loading

Assessment against linked issues

Objective Addressed Explanation
Fix: insights data not send [#660] No changes related to the Insights class or data transmission were observed.

Suggested labels

QA Approved, Ready to Merge

Poem

I'm a bunny coder, hopping with delight,
Tailwind and Vue make my code shine bright.
Fields and templates in neat array,
With every update, I happily play.
In the garden of code, I twirl and leap—
A rabbit's joy in changes so deep!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 30

🔭 Outside diff range comments (3)
admin/form-builder/assets/js/components/field-select/index.js (1)

8-28: Consider adding Pro version promotion handling.

Given the PR's objective to enhance Pro version promotions, consider adding methods to handle premium field options and show upgrade prompts when needed.

 data: function () {
     return {
         showOptions: false,
         selectedOption: 'Select an option',
+        isPremiumField: false,
     };
 },

 computed: {
     value: {
         get: function () {
             return this.editing_form_field[this.option_field.name];
         },

         set: function (value) {
             this.$store.commit('update_editing_form_field', {
                 editing_field_id: this.editing_form_field.id,
                 field_name: this.option_field.name,
                 value: value
             });
         }
     },
+    
+    showUpgradePrompt: function() {
+        return this.isPremiumField && !this.isProVersion;
+    }
 }
includes/Fields/Form_Field_Post_Title.php (2)

56-85: Consider removing unrelated mask options from post title field.

The mask options (phone, date, tax_id, etc.) seem inappropriate for a post title field and could lead to confusion. Consider moving this functionality to more appropriate field types.


134-134: Improve nonce verification handling.

The nonce check result is not being handled. If the check fails, the code continues execution.

Apply this diff to properly handle nonce verification:

-        check_ajax_referer( 'wpuf_form_add' );
+        if ( ! check_ajax_referer( 'wpuf_form_add', false, false ) ) {
+            wp_send_json_error( array( 'error' => __( 'Invalid nonce', 'wp-user-frontend' ) ) );
+        }
🧹 Nitpick comments (56)
admin/form-builder/assets/js/components/field-select/index.js (1)

8-13: LGTM! Consider enhancing state initialization.

The new data properties are well-structured for managing the select field's state. However, consider initializing selectedOption based on the current field value for better UX.

 data: function () {
     return {
         showOptions: false,
-        selectedOption: 'Select an option',
+        selectedOption: this.editing_form_field[this.option_field.name] || 'Select an option',
     };
 },
admin/form-builder/assets/js/components/help-text/template.php (1)

6-9: Enhance SVG accessibility and maintainability.

Consider these improvements:

  1. Add ARIA attributes for better accessibility
  2. Extract SVG path to a constant for better maintainability
-<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none">
+<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none"
+     role="img"
+     aria-label="Help information">
includes/Fields/Form_Field_MultiDropdown.php (1)

50-50: Fix typo and remove redundant attribute in select element.

There's a typo in the mulitple attribute and it's redundant since multiple="multiple" is already specified.

-                <select multiple="multiple" class="multiselect <?php echo 'wpuf_' . esc_attr( $field_settings['name'] ) . '_' . esc_attr( $form_id ); ?>" id="<?php echo esc_attr( $field_settings['name'] ) . '_' . esc_attr( $form_id ); ?>" name="<?php echo esc_attr( $name ); ?>" mulitple="multiple" data-required="<?php echo esc_attr( $field_settings['required'] ); ?>" data-type="multiselect">
+                <select multiple="multiple" class="multiselect <?php echo 'wpuf_' . esc_attr( $field_settings['name'] ) . '_' . esc_attr( $form_id ); ?>" id="<?php echo esc_attr( $field_settings['name'] ) . '_' . esc_attr( $form_id ); ?>" name="<?php echo esc_attr( $name ); ?>" data-required="<?php echo esc_attr( $field_settings['required'] ); ?>" data-type="multiselect">
includes/Admin/Forms/Admin_Form.php (2)

237-254: Remove commented-out code.

The old navigation tabs implementation is commented out but should be removed to maintain code cleanliness.

-<!--        <a href="#wpuf-metabox-settings"
-            :class="active_settings_tab === '#wpuf-metabox-settings' ? 'nav-tab-active' : ''"
-            class="nav-tab"><?php // esc_html_e( 'Post Settings', 'wp-user-frontend' ); ?></a>
-        <a href="#wpuf-metabox-settings-update"
-            :class="active_settings_tab === '#wpuf-metabox-settings-update' ? 'nav-tab-active' : ''"
-            class="nav-tab"><?php // esc_html_e( 'Edit Settings', 'wp-user-frontend' ); ?></a>
-        <a href="#wpuf-metabox-submission-restriction"
-            :class="active_settings_tab === '#wpuf-metabox-submission-restriction' ? 'nav-tab-active' : ''"
-            class="nav-tab"><?php // esc_html_e( 'Submission Restriction', 'wp-user-frontend' ); ?></a>
-        <a href="#wpuf-metabox-settings-payment"
-            :class="active_settings_tab === '#wpuf-metabox-settings-payment' ? 'nav-tab-active' : ''"
-            class="nav-tab"><?php // esc_html_e( 'Payment Settings', 'wp-user-frontend' ); ?></a>
-        <a href="#wpuf-metabox-settings-display"
-            :class="active_settings_tab === '#wpuf-metabox-settings-display' ? 'nav-tab-active' : ''"
-            class="nav-tab"><?php // esc_html_e( 'Display Settings', 'wp-user-frontend' ); ?></a>
-        <a href="#wpuf-metabox-post_expiration"
-            :class="active_settings_tab === '#wpuf-metabox-post_expiration' ? 'nav-tab-active' : ''"
-            class="nav-tab"><?php // esc_html_e( 'Post Expiration', 'wp-user-frontend' ); ?></a>-->

313-313: Move inline style to Tailwind CSS classes.

Replace the inline style with Tailwind CSS padding classes for consistency.

-        <div v-show="active_tab === 'notification'" id="wpuf-form-builder-notification" class="group wpuf-nav-tab" style="padding: 2rem">
+        <div v-show="active_tab === 'notification'" id="wpuf-form-builder-notification" class="group wpuf-nav-tab wpuf-p-8">
admin/form-builder/assets/js/components/form-post_excerpt/template.php (1)

6-6: Remove redundant default text binding.

The default text is being set in two places:

  1. Via :default_text prop binding
  2. Via template interpolation {{ field.default }}

This is redundant and could cause confusion.

Keep only the template interpolation:

-        :default_text="field.default"
         :rows="field.rows"
         :cols="field.cols"
     >{{ field.default }}</textarea>

Also applies to: 9-9

includes/Fields/Form_Field_reCaptcha.php (1)

140-140: Fix grammatical errors in text.

There are two text issues that need correction:

  1. "Click here to get the these key" has redundant "the"
  2. "Go to Setting" should be plural

Apply this diff to fix the text:

-                __( 'Click here to get the these key', 'wp-user-frontend' )
+                __( 'Click here to get these keys', 'wp-user-frontend' )
-                __( 'Go to Setting', 'wp-user-frontend' )
+                __( 'Go to Settings', 'wp-user-frontend' )

Also applies to: 146-146

admin/form-builder/assets/js/components/form-textarea_field/template.php (1)

2-8: LGTM! Consider using v-model for two-way binding.

The textarea implementation looks good with proper conditional rendering and attribute bindings. For better reactivity and consistency with Vue.js best practices, consider using v-model instead of the :default binding.

-        :default="field.default"
+        v-model="field.default"
includes/Fields/Form_Field_Text.php (1)

68-91: Consider moving inline JavaScript to a separate file.

The mask options JavaScript would be better maintained in a separate JS file for improved:

  • Code organization and maintainability
  • Cache optimization
  • Easier testing and debugging

Consider:

  1. Moving the mask options script to a dedicated JS file
  2. Enqueuing it properly using WordPress's wp_enqueue_script()
  3. Passing the mask options as data attributes or via wp_localize_script()

Example implementation:

// In the class constructor or init method
public function enqueue_scripts() {
    wp_enqueue_script(
        'wpuf-text-field-mask',
        WPUF_ASSET_URI . '/js/text-field-mask.js',
        array('jquery'),
        WPUF_VERSION,
        true
    );
}
// text-field-mask.js
jQuery(document).ready(function($) {
    function initTextFieldMask(field, maskType) {
        switch (maskType) {
            case 'us_phone':
                field.mask('(999) 999-9999');
                break;
            // ... other cases
        }
    }
    
    // Initialize masks for all text fields
    $('.wpuf-fields input[type="text"][data-mask]').each(function() {
        initTextFieldMask($(this), $(this).data('mask'));
    });
});
admin/form-builder/assets/js/mixins/form-field.js (1)

36-66: Improve maintainability of the builder_class_names method.

While the method provides consistent styling across field types, there are several areas for improvement:

  1. Consider extracting hardcoded classes into constants or a configuration object for better maintainability.
  2. Add comments explaining the styling decisions for each field type.
  3. Consider using Tailwind's @apply directive to reduce repetition.
  4. Review the use of !important (!wpuf-bg-primary) as it might indicate specificity issues.

Here's a suggested refactor:

+// Define common class configurations
+const FIELD_CLASSES = {
+  upload_btn: {
+    base: 'file-selector wpuf-rounded-md wpuf-btn-secondary',
+    description: '// Upload button with secondary styling'
+  },
+  radio: {
+    base: 'wpuf-ml-3 wpuf-block wpuf-text-sm wpuf-font-medium wpuf-leading-6 wpuf-text-gray-900',
+    states: 'checked:focus:!wpuf-bg-primary checked:hover:!wpuf-bg-primary checked:before:!wpuf-bg-white checked:!wpuf-bg-primary',
+    description: '// Radio button with primary color on checked state'
+  },
+  // ... other field types
+};

 builder_class_names: function(type_class) {
-    var commonClasses = '';
+    const config = FIELD_CLASSES[type_class] || FIELD_CLASSES.default;
+    const commonClasses = [config.base, config.states].filter(Boolean).join(' ');

-    switch (type_class) {
-        case 'upload_btn':
-            commonClasses = 'file-selector  wpuf-rounded-md wpuf-btn-secondary';
-            break;
-        // ... other cases
-    }

     return [
         type_class,
         this.required_class(),
         'wpuf_' + this.field.name + '_' + this.form_id,
         commonClasses
     ];
 },
assets/js/wpuf-form-builder.js (5)

93-96: Consider Using Array.find Instead

Using filter and then checking length is fine, but using Array.find would be slightly more readable if you only need the first matching element:
────────────────────────────────

- var field = state.form_fields.filter(function (item) {
-   return parseInt(field_id) === parseInt(item.id);
- });
- if (field.length) {
+ var field = state.form_fields.find(function (item) {
+   return parseInt(field_id) === parseInt(item.id);
+ });
+ if (field) {

106-108: Avoid Magic Number in Timeout

Consider storing 400 in a variable or making it configurable for clarity and maintainability.


170-189: Use Consistent i18n Formatting

When building HTML snippets with translated strings, ensure each placeholder (e.g., ‹span› or partial sentence) aligns with your i18n strategy to avoid accidental formatting issues or missing translations. Everything else in this modal logic looks fine.


551-555: onbeforeunload Warning

This is common practice. Just be aware that many modern browsers may limit the custom text shown to users.


1021-1025: Commented-Out resizeBuilderContainer

Remove or clarify the commented-out function calls if no longer needed, to keep the codebase tidy.

admin/form-builder/assets/js/form-builder.js (1)

332-332: Optional Chain Advice

Static analysis suggests using optional chaining if you frequently check sub-properties. If applicable, simplify for readability:
────────────────────────────────

// Instead of:
return something ? something.foo : false;

// Possibly:
return something?.foo || false;
assets/js-templates/form-components.php (5)

85-91: Use more descriptive alt text for improved accessibility.
The blank-state illustration currently has alt="". Consider providing a more descriptive alternative text for screen readers, for example: alt="No fields added yet - blank form preview".


92-116: Consider reducing repetition of utility classes.
Multiple Tailwind utility classes appear repeatedly (e.g., wpuf-flex, wpuf-bg-green-50, etc.). Extracting these into a shared helper or a small utility function might improve maintainability and consistency.


277-291: Add placeholder or empty-state handling for multiselect.
When option_field.options is empty, the user might be confused by a blank dropdown. Consider handling this case by displaying a placeholder option like “No items available.”


298-396: Bulk management enhancements for option data.
This chunk introduces toggles (show_value, sync_value) and a dynamic list of options. For large sets of options, a bulk add/remove feature or a drag-handle reordering might be more user-friendly.


1018-1146: Search filter and “panel-form-field-group” toggles.
The new model for searching and grouping form fields is great for user experience. As a small enhancement, consider trimming or sanitizing search input (searched_fields) to avoid potential side effects.

admin/form-builder/assets/js/components/field-option-pro-feature-alert/template.php (1)

1-7: LGTM! Consider adding aria-label for better accessibility.

The changes effectively enhance the Pro feature alert with improved styling and proper text escaping. The tooltip implementation provides clear user guidance.

Consider adding an aria-label to the link for better accessibility:

-        <a :href="pro_link" target="_blank"><img src="<?php echo wpuf_get_pro_icon() ?>" alt="pro icon"></a>
+        <a :href="pro_link" target="_blank" aria-label="<?php esc_attr_e( 'Upgrade to PRO version', 'wp-user-frontend' ); ?>">
+            <img src="<?php echo wpuf_get_pro_icon() ?>" alt="pro icon">
+        </a>
admin/form-builder/assets/js/components/form-post_title/template.php (1)

7-8: Consider consolidating class bindings.

The input element uses both dynamic :class and static class attributes, which could lead to conflicts. Consider consolidating them into a single computed property.

-        :class="class_names('textfield')"
-        class="wpuf-block wpuf-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300"
+        :class="[
+            class_names('textfield'),
+            'wpuf-block wpuf-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border wpuf-border-gray-300'
+        ]"
admin/form-builder/assets/js/components/form-post_tags/template.php (1)

4-5: Consider extracting Tailwind utility classes into a reusable class.

The large number of utility classes makes the template harder to maintain. Consider creating a reusable class in your CSS/LESS files or a computed property to encapsulate these styles.

- :class="builder_class_names('text')"
- class="wpuf-block wpuf-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300"
+ :class="[builder_class_names('text'), 'wpuf-form-input']"

Then define the styles in your CSS/LESS file:

.wpuf-form-input {
  @apply wpuf-block wpuf-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300;
}
admin/form-builder/assets/js/components/field-multiselect/template.php (1)

6-11: Enhance select element accessibility.

The multiselect lacks proper ARIA attributes for better screen reader support.

 <select
     :class="['term-list-selector']"
     class="wpuf-w-full wpuf-mt-2 wpuf-border-primary wpuf-z-30"
     v-model="value"
     multiple
+    :aria-label="option_field.title"
+    :aria-describedby="option_field.help_text ? 'help-text-' + _uid : null"
 >
admin/form-builder/assets/js/components/form-section_break/template.php (1)

1-19: LGTM! Well-structured section break implementation.

The changes provide:

  • Clear visual distinction between regular and dashed dividers
  • Consistent styling using Tailwind CSS
  • Proper semantic structure

However, consider adding a default case for unknown divider types to handle potential edge cases.

     <div
-        v-else-if="field.divider === 'dashed'"
+        v-else-if="field.divider === 'dashed'"
         class="wpuf-section-wrap">
         <!-- ... dashed divider content ... -->
     </div>
+    <div v-else class="wpuf-section-wrap">
+        <!-- fallback content for unknown divider types -->
+        <h2 class="wpuf-section-title wpuf-text-xs">{{ field.label }}</h2>
+        <div class="wpuf-section-details wpuf-text-sm wpuf-text-gray-500">{{ field.description }}</div>
+    </div>
admin/form-builder/assets/js/components/form-checkbox_field/template.php (2)

2-17: Improve accessibility for non-inline checkboxes.

The checkbox group needs ARIA attributes and consistent spacing.

Apply this diff to enhance accessibility and spacing:

     <div
         v-if="field.inline !== 'yes'"
+        role="group"
+        :aria-label="field.label || 'Checkbox group'"
         class="wpuf-space-y-2">
         <div
             v-if="has_options" v-for="(label, val) in field.options"
             class="wpuf-relative wpuf-flex wpuf-items-center">
             <div class="wpuf-flex wpuf-items-center">
                 <input
                     type="checkbox"
                     :value="val"
                     :checked="is_selected(val)"
+                    :aria-label="label"
                     :class="builder_class_names('checkbox')">
                 <label class="wpuf-ml-3 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label>
             </div>
         </div>
     </div>

19-34: Improve accessibility for inline checkboxes.

The inline checkbox group needs similar accessibility enhancements.

Apply this diff to enhance accessibility:

     <div
         v-else
+        role="group"
+        :aria-label="field.label || 'Checkbox group'"
         class="wpuf-flex"
     >
         <div
             v-if="has_options" v-for="(label, val) in field.options"
             class="wpuf-relative wpuf-flex wpuf-items-center wpuf-mr-4">
             <input
                 type="checkbox"
                 :value="val"
                 :checked="is_selected(val)"
+                :aria-label="label"
                 :class="class_names('checkbox_btns')"
                 class="!wpuf-mt-[.5px] wpuf-rounded wpuf-border-gray-300 wpuf-text-indigo-600">
             <label class="wpuf-ml-1 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label>
         </div>
     </div>
admin/form-builder/assets/js/components/field-radio/template.php (1)

22-39: Improve accessibility for inline radio buttons.

The radio group needs ARIA attributes for better accessibility.

Apply this diff to enhance accessibility:

     <div
         v-if="option_field.inline"
+        role="radiogroup"
+        :aria-label="option_field.title"
         class="wpuf-mt-2 wpuf-flex">
         <div
             v-for="(option, key, index) in option_field.options"
             class="wpuf-items-center">
             <label
                 :class="index !== 0 ? 'wpuf-ml-2' : ''"
                 class="wpuf-block text-sm/6 wpuf-font-medium wpuf-text-gray-900">
                 <input
                     type="radio"
                     :value="key"
                     v-model="value"
+                    :aria-label="option"
                     class="checked:!wpuf-bg-primary checked:before:!wpuf-bg-transparent">
                 {{ option }}
             </label>
         </div>
     </div>
admin/form-builder/assets/js/mixins/add-form-field.js (2)

20-31: LGTM! Consider adding ARIA attributes for accessibility.

The modal styling improvements with Tailwind CSS look great and align with the promotional UI enhancements.

Consider adding ARIA attributes for better accessibility:

 Swal.fire({
     title: '<span class="wpuf-text-orange-400">Oops...</span>',
     html: '<p class="wpuf-text-gray-500 wpuf-text-xl wpuf-m-0 wpuf-p-0">You already have this field in the form</p>',
     imageUrl: wpuf_form_builder.asset_url + '/images/oops.svg',
+    imageAlt: 'Oops error icon',
     showCloseButton: true,
     padding: '1rem',
     width: '35rem',
     customClass: {
         confirmButton: "!wpuf-flex focus:!wpuf-shadow-none !wpuf-bg-primary",
         closeButton: "wpuf-absolute"
     },
+    ariaDescribedBy: 'duplicate-field-error'
 });

57-61: LGTM! Consider adding type coercion for safer comparison.

The method correctly checks for pro features, but could benefit from explicit type handling.

Consider using explicit boolean coercion:

 is_pro_preview: function (template) {
-    var is_pro_active = wpuf_form_builder.is_pro_active === '1';
+    var is_pro_active = Boolean(Number(wpuf_form_builder.is_pro_active));
     return (!is_pro_active && this.field_settings[template] && this.field_settings[template].pro_feature);
 },
admin/form-builder/assets/js/components/field-visibility/template.php (2)

9-39: Consider extracting radio options into a reusable component.

The radio button implementation is well-structured but duplicates logic between inline and block modes.

Consider creating a reusable radio option component:

+<!-- radio-option.php -->
+<template>
+    <div :class="containerClasses">
+        <label class="wpuf-block wpuf-font-medium wpuf-text-gray-900">
+            <input
+                type="radio"
+                :value="value"
+                v-model="selected"
+                class="checked:!wpuf-bg-primary checked:before:!wpuf-bg-transparent">
+            {{ label }}
+        </label>
+    </div>
+</template>

Then use it in both modes:

-<div v-if="!option_field.inline"
-    class="wpuf-flex wpuf-items-center wpuf-gap-x-2 wpuf-m-2"
-    v-for="(option, key) in option_field.options">
+<radio-option
+    v-for="(option, key) in option_field.options"
+    :key="key"
+    :value="key"
+    :label="option"
+    :inline="option_field.inline"
+    v-model="selected"/>

60-83: Consider using Vue templating for subscription options.

While the current PHP implementation works, using Vue templating would provide better maintainability and dynamic updates.

Consider moving subscription data to Vue:

+<script>
+export default {
+    data() {
+        return {
+            subscriptions: <?php echo json_encode(wpuf()->subscription->get_subscriptions()); ?>
+        }
+    }
+}
+</script>

-<ul>
-    <?php
-        if ( class_exists( 'WPUF_Subscription' ) ) {
-            $subscriptions  = wpuf()->subscription->get_subscriptions();
-            // ... PHP logic
-        }
-    ?>
-</ul>
+<ul v-if="subscriptions && subscriptions.length">
+    <li v-for="pack in subscriptions" :key="pack.ID" class="wpuf-mt-2">
+        <label>
+            <input
+                class="wpuf-bg-transparent wpuf-shadow-primary"
+                type="checkbox"
+                v-model="choices"
+                :value="pack.ID">
+            {{ pack.post_title }}
+        </label>
+    </li>
+    <li v-if="!subscriptions.length">
+        {{ i18n.no_subscription_plan }}
+    </li>
+</ul>
admin/form-builder/assets/js/mixins/global.js (1)

10-12: Consider adding type safety to pro status check.

The strict comparison with string '1' works but could be more robust with proper type handling.

Consider using explicit type conversion:

 is_pro_active: function () {
-    return wpuf_form_builder.is_pro_active === '1';
+    return Boolean(Number(wpuf_form_builder.is_pro_active));
 },
admin/form-builder/assets/js/components/field-option-data/template.php (1)

74-102: Consider adding ARIA labels for better accessibility.

The SVG icons for delete and add actions need accessibility improvements.

 <div
     @click="delete_option(index)"
-    class="action-buttons hover:wpuf-cursor-pointer">
+    class="action-buttons hover:wpuf-cursor-pointer"
+    role="button"
+    aria-label="Delete option">
     <svg
         xmlns="http://www.w3.org/2000/svg"
         fill="none"
         viewBox="0 0 24 24"
         stroke-width="1.5"
         stroke="currentColor"
+        aria-hidden="true"
         class="wpuf-size-6 wpuf-border wpuf-rounded-2xl wpuf-border-gray-400 hover:wpuf-border-primary wpuf-p-1">
         <path stroke-linecap="round" stroke-linejoin="round" d="M5 12h14" />
     </svg>
 </div>

Similar changes for the add button:

 <div
     v-if="index === options.length - 1"
     @click="add_option"
-    class="plus-buttons hover:wpuf-cursor-pointer !wpuf-border-0">
+    class="plus-buttons hover:wpuf-cursor-pointer !wpuf-border-0"
+    role="button"
+    aria-label="Add new option">
     <svg
         xmlns="http://www.w3.org/2000/svg"
         fill="none"
         viewBox="0 0 24 24"
         stroke-width="1.5"
         stroke="currentColor"
+        aria-hidden="true"
         class="wpuf-ml-1 wpuf-size-6 wpuf-border wpuf-rounded-2xl wpuf-border-gray-400 wpuf-p-1">
admin/form-builder/assets/js/components/builder-stage-v4-1/index.js (2)

144-146: Simplify boolean expressions.

The ternary operator returning boolean literals can be simplified.

-            return ( this.field_settings[template] && this.field_settings[template].pro_feature ) ? true : false;
+            return !!(this.field_settings[template]?.pro_feature);
🧰 Tools
🪛 Biome (1.9.4)

[error] 145-145: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 145-145: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


113-132: Remove unnecessary this alias.

The arrow function inherits this from the enclosing scope, making the alias unnecessary.

-            var self = this;
-
-            (Swal.fire({
+            (Swal.fire({
                 text: this.i18n.delete_field_warn_msg,
                 icon: 'warning',
                 showCancelButton: true,
                 confirmButtonColor: '#d54e21',
-                confirmButtonText: self.i18n.yes_delete_it,
-                cancelButtonText: self.i18n.no_cancel_it,
+                confirmButtonText: this.i18n.yes_delete_it,
+                cancelButtonText: this.i18n.no_cancel_it,
                 customClass: {
                     confirmButton: 'btn btn-success',
                     cancelButton: 'btn btn-danger',
                 }
             })).then((result) => {
                 if (result.isConfirmed) {
-                    self.$store.commit('delete_form_field_element', index);
+                    this.$store.commit('delete_form_field_element', index);
                 }
             });
🧰 Tools
🪛 Biome (1.9.4)

[error] 114-114: This aliasing of this is unnecessary.

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

(lint/complexity/noUselessThisAlias)

admin/form-builder/assets/js/components/form-fields-v4-1/template.php (1)

4-10: Add ARIA attributes to improve search input accessibility.

The search input should have appropriate ARIA attributes for better accessibility.

     <input
         type="text"
         name="search"
         id="search"
         v-model="searched_fields"
+        aria-label="Search form fields"
+        role="searchbox"
         class="!wpuf-border-none !wpuf-rounded-lg wpuf-block wpuf-min-w-0 wpuf-grow wpuf-px-4 wpuf-py-1.5 wpuf-text-base wpuf-text-gray-900 placeholder:wpuf-text-gray-400 sm:wpuf-text-sm/6 !wpuf-shadow-none !wpuf-ring-transparent"
         placeholder="<?php esc_attr_e( 'Search Field', 'wp-user-frontend' ); ?>">
includes/Fields/Form_Pro_Upgrade_Fields.php (1)

69-69: Replace WPUF_SINCE placeholder with actual version number.

The @SInCE tags in both new field classes use a placeholder WPUF_SINCE. This should be replaced with the actual version number where these features are being introduced.

Also applies to: 82-82

admin/form-builder/assets/js/components/form-column_field/template.php (1)

110-116: Consider extracting SVG icon to a separate component.

The inline SVG could be moved to a separate component for better maintainability and reusability.

admin/form-builder/assets/js/components/form-fields-v4-1/index.js (2)

33-49: Consider using Vue's built-in drag-and-drop functionality.

The code uses jQuery UI for drag-and-drop functionality, which creates a dependency on jQuery and may not align well with Vue's reactivity system. Consider using Vue's native drag-and-drop directives or a Vue-specific library like vuedraggable.

-Vue.nextTick(function () {
-    var buttons = $(self.$el).find('.panel-form-field-buttons .wpuf-field-button');
-
-    buttons.each(function () {
-        if ($(this).draggable('instance')) {
-            $(this).draggable('destroy');
-        }
-    });
-
-    buttons.draggable({
-        connectToSortable: '#form-preview-stage, #form-preview-stage .wpuf-form, .wpuf-column-inner-fields .wpuf-column-fields-sortable-list',
-        helper: 'clone',
-        revert: 'invalid',
-        cancel: '.button-faded',
-    }).disableSelection();
-});
+<draggable
+  v-model="form_fields"
+  :options="{
+    group: 'fields',
+    disabled: false,
+    handle: '.move'
+  }"
+  class="panel-form-field-buttons"
+>
+  <div
+    v-for="field in form_fields"
+    :key="field.id"
+    class="wpuf-field-button"
+    :class="{ 'button-faded': isDisabled(field) }"
+  >
+    <!-- Field content -->
+  </div>
+</draggable>

61-130: Enhance alert dialog accessibility and user experience.

The SweetAlert implementation could be improved for better accessibility and user experience:

  1. Missing ARIA labels for better screen reader support
  2. No keyboard navigation support
  3. Hardcoded dimensions might not be responsive
 Swal.fire({
     html: html,
     showCloseButton: true,
     customClass: {
         confirmButton: "!wpuf-flex focus:!wpuf-shadow-none",
-        closeButton: "wpuf-absolute"
+        closeButton: "wpuf-absolute",
+        container: "wpuf-dialog-container"
     },
-    width: '50rem',
+    width: 'auto',
+    maxWidth: '50rem',
     padding: '1.5rem',
     confirmButtonColor: '#F97316',
-    confirmButtonText: this.i18n.upgrade_to_pro
+    confirmButtonText: this.i18n.upgrade_to_pro,
+    focusConfirm: true,
+    returnFocus: true,
+    role: 'dialog',
+    ariaLabel: `${title} ${this.i18n.is_a_pro_feature}`
 })
includes/Admin/template-parts/modal-v4.1.php (1)

130-168: Improve JavaScript event handling and memory management.

The JavaScript code could be improved for better event handling and memory management.

 ( function ( $ ) {
     var popup = {
+        $modal: null,
+        $wrap: null,
+
+        init: function () {
+            this.$modal = $('.wpuf-form-template-modal');
+            this.$wrap = $('#wpbody-content .wrap');
+
-            $( '.wrap' ).on( 'click', 'a.page-title-action.add-form', this.openModal );
-            $( '.wpuf-form-template-modal .wpuf-close-btn' ).on( 'click', $.proxy( this.closeModal, this ) );
+            this.$wrap.on('click', 'a.page-title-action.add-form', this.openModal.bind(this));
+            this.$modal.on('click', '.wpuf-close-btn', this.closeModal.bind(this));
 
-            $( 'body' ).on( 'keydown', $.proxy( this.onEscapeKey, this ) );
+            $(document).on('keydown', this.onEscapeKey.bind(this));
         },
 
         openModal: function ( e ) {
             e.preventDefault();
 
-            $( '.wpuf-form-template-modal' ).show();
-            $( '#wpbody-content .wrap' ).hide();
+            this.$modal.show();
+            this.$wrap.hide();
+            this.$modal.find('.wpuf-close-btn').focus();
         },
 
         onEscapeKey: function ( e ) {
-            if (27 === e.keyCode) {
+            if (e.key === 'Escape') {
                 this.closeModal( e );
             }
         },
 
         closeModal: function ( e ) {
-            if (typeof e !== 'undefined') {
+            if (e) {
                 e.preventDefault();
             }
 
-            $( '.wpuf-form-template-modal' ).hide();
-            $( '#wpbody-content .wrap' ).show();
+            this.$modal.hide();
+            this.$wrap.show();
+            this.$wrap.find('a.page-title-action.add-form').focus();
         }
     };
 
-    $( function () {
+    $(function() {
         popup.init();
+        
+        // Cleanup on page unload
+        $(window).on('unload', function() {
+            popup.$wrap.off('click');
+            popup.$modal.off('click');
+            $(document).off('keydown');
+        });
     } );
 
 } )( jQuery );
Gruntfile.js (2)

3-5: Consider using a more flexible configuration approach.

The hardcoded file mapping could be moved to a separate configuration file for better maintainability.

-const tailwindFileMap = {
-    'admin/form-builder/views/form-builder-v4.1.php': 'admin/form-builder.css',
-}
+const tailwindConfig = require('./tailwind.config.json');
+const tailwindFileMap = tailwindConfig.fileMap;

121-133: Optimize watch task configuration.

The watch task could be optimized to reduce unnecessary rebuilds and improve performance.

 tailwind: {
     files: [
-        'src/css/**/*.css',
-        'admin/form-builder/views/*.php',
-        'admin/form-builder/assets/js/**/*.php',
-        'admin/form-builder/assets/js/**/*.js',
-        'includes/Admin/**/*.php',
+        'src/css/**/*.css',
+        'tailwind.config.js',
+        'admin/form-builder/**/*.{php,js}',
+        'includes/Admin/**/*.php'
     ],
-    tasks: ['shell:tailwind:src/css/admin/form-builder.css:assets/css/admin/form-builder.css'],
+    tasks: ['tailwind'],
     options: {
-        spawn: false
+        spawn: false,
+        debounceDelay: 250
     }
 },
admin/form-builder/assets/js/components/builder-stage-v4-1/template.php (2)

1-6: Improve empty state messaging and accessibility.

The empty state could be enhanced with better accessibility and user guidance.

-<div id="form-preview-stage" class="wpuf-h-[80vh]">
+<div 
+    id="form-preview-stage" 
+    class="wpuf-h-[80vh]"
+    role="region"
+    aria-label="<?php esc_attr_e('Form Preview Stage', 'wp-user-frontend'); ?>">
     <div v-if="!form_fields.length" 
-        class="wpuf-flex wpuf-flex-col wpuf-items-center wpuf-justify-center wpuf-h-[80vh]">
+        class="wpuf-flex wpuf-flex-col wpuf-items-center wpuf-justify-center wpuf-h-[80vh]"
+        role="status"
+        aria-live="polite">
         <img src="<?php echo WPUF_ASSET_URI . '/images/form-blank-state.svg'; ?>" 
+            alt="<?php esc_attr_e('Empty form illustration', 'wp-user-frontend'); ?>"
-            alt="">
-        <h2 class="wpuf-text-lg wpuf-text-gray-800"><?php esc_html_e( 'Add fields and build your desired form', 'wp-user-frontend' ); ?></h2>
+        <h2 class="wpuf-text-lg wpuf-text-gray-800">
+            <?php esc_html_e('Start Building Your Form', 'wp-user-frontend'); ?>
+        </h2>
         <p class="wpuf-text-sm wpuf-text-gray-500">
-            <?php esc_html_e( 'Add fields and build your desired form', 'wp-user-frontend' ); ?>
+            <?php esc_html_e('Drag and drop fields from the sidebar to start building your form', 'wp-user-frontend'); ?>
         </p>
     </div>

124-169: Improve hidden fields section organization and accessibility.

The hidden fields section could be better organized and more accessible.

-<div v-if="hidden_fields.length" class="wpuf-border-t wpuf-border-dashed wpuf-border-gray-300 wpuf-mt-2">
+<section 
+    v-if="hidden_fields.length" 
+    class="wpuf-border-t wpuf-border-dashed wpuf-border-gray-300 wpuf-mt-2"
+    aria-labelledby="hidden-fields-title">
-    <h4><?php esc_html_e( 'Hidden Fields', 'wp-user-frontend' ); ?></h4>
+    <h4 id="hidden-fields-title" class="wpuf-text-lg wpuf-font-medium wpuf-mb-4">
+        <?php esc_html_e('Hidden Fields', 'wp-user-frontend'); ?>
+        <span class="wpuf-text-sm wpuf-text-gray-500">
+            (<?php echo sprintf(esc_html__('%d fields', 'wp-user-frontend'), count($hidden_fields)); ?>)
+        </span>
+    </h4>
-    <ul class="wpuf-form">
+    <ul 
+        class="wpuf-form"
+        role="list"
+        aria-label="<?php esc_attr_e('Hidden Form Fields', 'wp-user-frontend'); ?>">
assets/js/wpuf-form-builder-mixins.js (1)

109-139: Consider extracting class mapping to a configuration object.

The builder_class_names method contains hardcoded class names for different field types. Consider extracting these into a configuration object for better maintainability.

+const FIELD_CLASS_MAPPING = {
+    upload_btn: 'file-selector wpuf-rounded-md wpuf-btn-secondary',
+    radio: 'wpuf-ml-3 wpuf-block wpuf-text-sm wpuf-font-medium wpuf-leading-6 wpuf-text-gray-900 checked:focus:!wpuf-bg-primary checked:hover:!wpuf-bg-primary checked:before:!wpuf-bg-white checked:!wpuf-bg-primary',
+    checkbox: 'wpuf-h-4 wpuf-w-4 wpuf-rounded wpuf-border-gray-300 !wpuf-mt-0.5 checked:focus:!wpuf-bg-primary checked:hover:wpuf-bg-primary checked:!wpuf-bg-primary before:!wpuf-content-none',
+    dropdown: 'wpuf-block wpuf-w-full wpuf-min-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300',
+    default: 'wpuf-block wpuf-min-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full'
+};

 builder_class_names: function(type_class) {
-    var commonClasses = '';
-    switch (type_class) {
-        case 'upload_btn':
-            commonClasses = 'file-selector  wpuf-rounded-md wpuf-btn-secondary';
-            break;
-        // ... other cases
-    }
+    var commonClasses = FIELD_CLASS_MAPPING[type_class] || FIELD_CLASS_MAPPING.default;
admin/form-builder/views/form-builder-v4.1.php (3)

13-18: Add ARIA label for title input field.

The title input field lacks an ARIA label for screen readers.

 <input
     @click="post_title_editing = !post_title_editing"
     v-model="post.post_title"
     type="text"
     name="post_title"
+    aria-label="<?php esc_attr_e( 'Form Title', 'wp-user-frontend' ); ?>"
     :class="post_title_editing ? '' : '!wpuf-border-0'"
     class="wpuf-text-gray-900 placeholder:wpuf-text-gray-400 wpuf-font-medium wpuf-min-w-16 wpuf-max-w-32">

29-34: Add ARIA label and role for form switcher button.

The form switcher button lacks proper ARIA attributes for accessibility.

 <div
     tabindex="0"
-    role="button"
+    role="combobox"
+    aria-label="<?php esc_attr_e( 'Switch Form', 'wp-user-frontend' ); ?>"
+    aria-expanded="false"
+    aria-controls="form-switcher-dropdown"
     class="wpuf-btn wpuf-m-1 wpuf-h-min wpuf-min-h-min wpuf-border-0 wpuf-ring-0 wpuf-shadow-none wpuf-p-0">

35-47: Add ARIA label and role for form switcher dropdown.

The form switcher dropdown lacks proper ARIA attributes for accessibility.

-<ul tabindex="0" class="wpuf-absolute wpuf-dropdown-content wpuf-menu !wpuf-p-0 wpuf-rounded-md wpuf-z-[1] wpuf-w-52 wpuf-shadow wpuf-bg-white !wpuf-right-[-4rem] !wpuf-top-8">
+<ul
+    id="form-switcher-dropdown"
+    role="listbox"
+    aria-label="<?php esc_attr_e( 'Available Forms', 'wp-user-frontend' ); ?>"
+    tabindex="0"
+    class="wpuf-absolute wpuf-dropdown-content wpuf-menu !wpuf-p-0 wpuf-rounded-md wpuf-z-[1] wpuf-w-52 wpuf-shadow wpuf-bg-white !wpuf-right-[-4rem] !wpuf-top-8">
includes/Admin/Forms/Admin_Form_Builder.php (1)

399-399: Reduce transient expiration time.

The transient expiration time of 1 day might be too long for frequently updated pro field assets.

-set_transient( self::PRO_FIELD_ASSETS, $info, DAY_IN_SECONDS );
+set_transient( self::PRO_FIELD_ASSETS, $info, 6 * HOUR_IN_SECONDS );
admin/form-builder/views/settings-sidebar.php (2)

88-93: Add ARIA label for checkbox input.

The checkbox input lacks an ARIA label for screen readers.

 <input
     :class="[setting_class_names('checkbox'), '!wpuf-mr-2']"
     type="checkbox"
     name="wpuf_settings[<?php echo $field_key; ?>]"
+    aria-label="<?php echo esc_attr( $field['label'] ); ?>"
     id="<?php echo $field_key; ?>"/>

172-178: Add placeholder and maxlength attributes for text input.

The text input field could benefit from placeholder text and maxlength attributes.

 <input
     :class="setting_class_names('text')"
     type="<?php echo $field['type']; ?>"
     name="wpuf_settings[<?php echo $field_key; ?>]"
     id="<?php echo $field_key; ?>"
+    placeholder="<?php echo esc_attr( $field['label'] ); ?>"
+    maxlength="<?php echo ! empty( $field['maxlength'] ) ? esc_attr( $field['maxlength'] ) : ''; ?>"
     value="<?php echo $value; ?>"/>
includes/Admin/Admin_Subscription.php (2)

11-11: Consider splitting the Admin_Subscription class

The class handles multiple responsibilities (subscription management, user profiles, admin UI, payments), violating the Single Responsibility Principle. Consider splitting it into focused classes:

  • SubscriptionManager
  • UserProfileHandler
  • AdminUIController
  • PaymentProcessor

This would improve maintainability and testability.

Also applies to: 183-281


183-281: Refactor long method profile_subscription_update

This method is too long (>100 lines) and handles multiple concerns. Consider breaking it down into smaller, focused methods:

  • validateSubscriptionUpdate()
  • handlePackageAssignment()
  • processPayment()
  • updateUserMeta()
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9801b41 and 69c6621.

⛔ Files ignored due to path filters (51)
  • assets/images/adjustments-horizontal.svg is excluded by !**/*.svg
  • assets/images/arrow-up-tray.svg is excluded by !**/*.svg
  • assets/images/badge-check.svg is excluded by !**/*.svg
  • assets/images/check-circle.svg is excluded by !**/*.svg
  • assets/images/checked-green.svg is excluded by !**/*.svg
  • assets/images/chevron-down.svg is excluded by !**/*.svg
  • assets/images/clock.svg is excluded by !**/*.svg
  • assets/images/cloud.svg is excluded by !**/*.svg
  • assets/images/code-bracket-square.svg is excluded by !**/*.svg
  • assets/images/code.svg is excluded by !**/*.svg
  • assets/images/cog-8-tooth.svg is excluded by !**/*.svg
  • assets/images/command-line.svg is excluded by !**/*.svg
  • assets/images/crown-white.svg is excluded by !**/*.svg
  • assets/images/document-check.svg is excluded by !**/*.svg
  • assets/images/exclamation-circle.svg is excluded by !**/*.svg
  • assets/images/eye-off.svg is excluded by !**/*.svg
  • assets/images/form-blank-state.svg is excluded by !**/*.svg
  • assets/images/globe-alt.svg is excluded by !**/*.svg
  • assets/images/key-rounded.svg is excluded by !**/*.svg
  • assets/images/link.svg is excluded by !**/*.svg
  • assets/images/location-marker.svg is excluded by !**/*.svg
  • assets/images/lock-icon-rounded-bg.svg is excluded by !**/*.svg
  • assets/images/mail.svg is excluded by !**/*.svg
  • assets/images/map.svg is excluded by !**/*.svg
  • assets/images/menu-alt-2.svg is excluded by !**/*.svg
  • assets/images/menu-alt-4.svg is excluded by !**/*.svg
  • assets/images/minus-circle-green.svg is excluded by !**/*.svg
  • assets/images/oops.svg is excluded by !**/*.svg
  • assets/images/photograph.svg is excluded by !**/*.svg
  • assets/images/play.svg is excluded by !**/*.svg
  • assets/images/plus-circle-green.svg is excluded by !**/*.svg
  • assets/images/qrcode.svg is excluded by !**/*.svg
  • assets/images/queue-list.svg is excluded by !**/*.svg
  • assets/images/recaptcha-placeholder.png is excluded by !**/*.png
  • assets/images/rectangle-stack.svg is excluded by !**/*.svg
  • assets/images/squares-2x2.svg is excluded by !**/*.svg
  • assets/images/squares-2x2.zip is excluded by !**/*.zip
  • assets/images/star.svg is excluded by !**/*.svg
  • assets/images/stop.svg is excluded by !**/*.svg
  • assets/images/tag.svg is excluded by !**/*.svg
  • assets/images/templates/blank.svg is excluded by !**/*.svg
  • assets/images/templates/edd.png is excluded by !**/*.png
  • assets/images/templates/edd.svg is excluded by !**/*.svg
  • assets/images/templates/event.svg is excluded by !**/*.svg
  • assets/images/templates/post.png is excluded by !**/*.png
  • assets/images/templates/post.svg is excluded by !**/*.svg
  • assets/images/templates/woocommerce.png is excluded by !**/*.png
  • assets/images/templates/woocommerce.svg is excluded by !**/*.svg
  • assets/images/title.svg is excluded by !**/*.svg
  • assets/images/view-columns.svg is excluded by !**/*.svg
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (107)
  • Gruntfile.js (5 hunks)
  • Lib/Appsero/Client.php (1 hunks)
  • admin/form-builder/assets/js/components/builder-stage-v4-1/index.js (1 hunks)
  • admin/form-builder/assets/js/components/builder-stage-v4-1/template.php (1 hunks)
  • admin/form-builder/assets/js/components/builder-stage/index.js (1 hunks)
  • admin/form-builder/assets/js/components/field-checkbox/index.js (1 hunks)
  • admin/form-builder/assets/js/components/field-checkbox/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-multiselect/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-option-data/index.js (1 hunks)
  • admin/form-builder/assets/js/components/field-option-data/template.php (4 hunks)
  • admin/form-builder/assets/js/components/field-option-pro-feature-alert/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-options/index.js (1 hunks)
  • admin/form-builder/assets/js/components/field-options/template.php (2 hunks)
  • admin/form-builder/assets/js/components/field-radio/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-select/index.js (2 hunks)
  • admin/form-builder/assets/js/components/field-select/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-text-meta/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-text/index.js (1 hunks)
  • admin/form-builder/assets/js/components/field-text/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-textarea/index.js (1 hunks)
  • admin/form-builder/assets/js/components/field-textarea/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-visibility/index.js (1 hunks)
  • admin/form-builder/assets/js/components/field-visibility/template.php (3 hunks)
  • admin/form-builder/assets/js/components/form-checkbox_field/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-column_field/index.js (4 hunks)
  • admin/form-builder/assets/js/components/form-column_field/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-custom_hidden_field/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-dropdown_field/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-email_address/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-featured_image/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-fields-v4-1/index.js (1 hunks)
  • admin/form-builder/assets/js/components/form-fields-v4-1/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-fields/index.js (1 hunks)
  • admin/form-builder/assets/js/components/form-image_upload/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-multiple_select/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-post_content/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-post_excerpt/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-post_tags/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-post_title/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-radio_field/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-recaptcha/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-section_break/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-taxonomy/template.php (3 hunks)
  • admin/form-builder/assets/js/components/form-text_field/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-textarea_field/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-website_url/template.php (1 hunks)
  • admin/form-builder/assets/js/components/help-text/index.js (1 hunks)
  • admin/form-builder/assets/js/components/help-text/template.php (1 hunks)
  • admin/form-builder/assets/js/form-builder.js (17 hunks)
  • admin/form-builder/assets/js/mixins/add-form-field.js (2 hunks)
  • admin/form-builder/assets/js/mixins/form-field.js (3 hunks)
  • admin/form-builder/assets/js/mixins/global.js (1 hunks)
  • admin/form-builder/assets/js/mixins/option-field.js (1 hunks)
  • admin/form-builder/assets/less/form-builder.less (3 hunks)
  • admin/form-builder/assets/less/variables.less (1 hunks)
  • admin/form-builder/views/form-builder-v4.1.php (1 hunks)
  • admin/form-builder/views/form-builder.php (2 hunks)
  • admin/form-builder/views/settings-sidebar.php (1 hunks)
  • assets/css/admin.css (0 hunks)
  • assets/css/frontend-forms.css (2 hunks)
  • assets/css/wpuf-form-builder.css (3 hunks)
  • assets/js-templates/form-components.php (19 hunks)
  • assets/js/wpuf-form-builder-components.js (15 hunks)
  • assets/js/wpuf-form-builder-mixins.js (7 hunks)
  • assets/js/wpuf-form-builder-wpuf-forms.js (2 hunks)
  • assets/js/wpuf-form-builder.js (17 hunks)
  • assets/less/admin.less (0 hunks)
  • assets/less/frontend-forms.less (2 hunks)
  • includes/Admin/Admin_Subscription.php (1 hunks)
  • includes/Admin/Forms/Admin_Form.php (4 hunks)
  • includes/Admin/Forms/Admin_Form_Builder.php (7 hunks)
  • includes/Admin/Forms/Post/Templates/Form_Template.php (3 hunks)
  • includes/Admin/Forms/Post/Templates/Post_Form_Template_Events_Calendar.php (1 hunks)
  • includes/Admin/Forms/Post/Templates/Post_Form_Template_Post.php (1 hunks)
  • includes/Admin/Forms/Post/Templates/Post_Form_Template_WooCommerce.php (1 hunks)
  • includes/Admin/Forms/Post/Templates/Pro_Form_Preview_EDD.php (1 hunks)
  • includes/Admin/Forms/Template_Post.php (1 hunks)
  • includes/Admin/Menu.php (1 hunks)
  • includes/Admin/Posting.php (2 hunks)
  • includes/Admin/template-parts/modal-v4.1.php (1 hunks)
  • includes/Admin/template-parts/modal.php (5 hunks)
  • includes/Admin/views/post-form.php (1 hunks)
  • includes/Assets.php (1 hunks)
  • includes/Fields/Field_Contract.php (2 hunks)
  • includes/Fields/Form_Field_Checkbox.php (1 hunks)
  • includes/Fields/Form_Field_Cloudflare_Turnstile.php (1 hunks)
  • includes/Fields/Form_Field_Column.php (2 hunks)
  • includes/Fields/Form_Field_Dropdown.php (1 hunks)
  • includes/Fields/Form_Field_Email.php (1 hunks)
  • includes/Fields/Form_Field_Featured_Image.php (2 hunks)
  • includes/Fields/Form_Field_Hidden.php (1 hunks)
  • includes/Fields/Form_Field_Image.php (1 hunks)
  • includes/Fields/Form_Field_MultiDropdown.php (1 hunks)
  • includes/Fields/Form_Field_Numeric.php (0 hunks)
  • includes/Fields/Form_Field_Post_Content.php (1 hunks)
  • includes/Fields/Form_Field_Post_Excerpt.php (1 hunks)
  • includes/Fields/Form_Field_Post_Tags.php (1 hunks)
  • includes/Fields/Form_Field_Post_Taxonomy.php (1 hunks)
  • includes/Fields/Form_Field_Post_Title.php (3 hunks)
  • includes/Fields/Form_Field_Radio.php (1 hunks)
  • includes/Fields/Form_Field_SectionBreak.php (2 hunks)
  • includes/Fields/Form_Field_Text.php (1 hunks)
  • includes/Fields/Form_Field_Textarea.php (2 hunks)
  • includes/Fields/Form_Field_reCaptcha.php (2 hunks)
  • includes/Fields/Form_Pro_Upgrade_Fields.php (16 hunks)
  • includes/Frontend_Render_Form.php (1 hunks)
  • includes/Pro_Upgrades.php (1 hunks)
⛔ Files not processed due to max files limit (7)
  • includes/Setup_Wizard.php
  • languages/wp-user-frontend.pot
  • package.json
  • src/css/admin/form-builder.css
  • tailwind.config.js
  • tests/chrome_recordings/post form templates.json
  • wpuf-functions.php
💤 Files with no reviewable changes (3)
  • assets/less/admin.less
  • includes/Fields/Form_Field_Numeric.php
  • assets/css/admin.css
✅ Files skipped from review due to trivial changes (19)
  • admin/form-builder/assets/less/variables.less
  • includes/Fields/Form_Field_Image.php
  • includes/Fields/Form_Field_Dropdown.php
  • includes/Fields/Form_Field_Checkbox.php
  • includes/Admin/Forms/Post/Templates/Post_Form_Template_Events_Calendar.php
  • includes/Fields/Form_Field_Radio.php
  • includes/Fields/Form_Field_Post_Content.php
  • includes/Admin/template-parts/modal.php
  • includes/Fields/Form_Field_Email.php
  • admin/form-builder/views/form-builder.php
  • includes/Admin/Forms/Post/Templates/Post_Form_Template_Post.php
  • includes/Fields/Form_Field_Post_Taxonomy.php
  • includes/Fields/Field_Contract.php
  • includes/Fields/Form_Field_Post_Tags.php
  • includes/Admin/Forms/Post/Templates/Post_Form_Template_WooCommerce.php
  • includes/Assets.php
  • includes/Fields/Form_Field_Hidden.php
  • admin/form-builder/assets/js/components/form-multiple_select/template.php
  • includes/Fields/Form_Field_Post_Excerpt.php
🧰 Additional context used
🪛 Biome (1.9.4)
admin/form-builder/assets/js/components/builder-stage-v4-1/index.js

[error] 145-145: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 145-145: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 168-168: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 176-176: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 114-114: This aliasing of this is unnecessary.

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

(lint/complexity/noUselessThisAlias)

admin/form-builder/assets/js/components/form-fields-v4-1/index.js

[error] 135-135: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

admin/form-builder/assets/js/form-builder.js

[error] 617-617: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

assets/js/wpuf-form-builder.js

[error] 617-617: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

assets/js/wpuf-form-builder-components.js

[error] 332-332: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 332-332: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 355-355: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 363-363: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 301-301: This aliasing of this is unnecessary.

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

(lint/complexity/noUselessThisAlias)


[error] 1683-1683: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (120)
includes/Admin/Forms/Post/Templates/Pro_Form_Preview_EDD.php (1)

30-30: LGTM! The SVG format update aligns with the broader UI enhancement goals.

The change from PNG to SVG format is a good improvement as SVGs provide:

  • Better scaling across different screen sizes
  • Smaller file size for simple graphics
  • Crisper display on high-DPI screens

Let's verify that the SVG asset exists and is accessible:

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Check if the SVG file exists and is accessible
if [ -f "assets/images/templates/edd.svg" ]; then
    echo "SVG file exists"
    # Check file permissions
    ls -l "assets/images/templates/edd.svg"
else
    echo "SVG file not found"
fi

Length of output: 207


SVG Asset Verified: The SVG file exists and is accessible.

  • Confirmed that "assets/images/templates/edd.svg" exists.
  • File permissions are properly set (-rw-r--r--).
includes/Fields/Form_Field_Column.php (2)

13-13: LGTM! Icon update aligns with UI enhancements.

The icon change from 'columns' to 'view-columns' provides a more semantically accurate representation of the field's purpose.


83-83: LGTM! Help text is now more descriptive and accurate.

The updated help text clearly communicates:

  1. The field's purpose (column count configuration)
  2. The maximum limit (3 columns)

This matches with the field's properties where max_column is set to 3 (line 139).

includes/Fields/Form_Field_Featured_Image.php (2)

15-15: LGTM! Icon update aligns with UI enhancements.

The icon change from 'file-image-o' to 'photograph' provides a more modern and semantically accurate representation of the featured image field.


113-113: LGTM! Appropriate exclusion of width option.

Excluding the 'width' option from default settings is appropriate since featured images typically follow theme-defined dimensions.

admin/form-builder/assets/js/components/help-text/template.php (2)

1-10: LGTM! Clean transition from Font Awesome to SVG.

The implementation provides better scalability and customization while reducing external dependencies.


3-5: Verify tooltip behavior in complex layouts.

The tooltip container is set to "body" which might cause z-index issues in complex modal or popup scenarios.

Please test the tooltip visibility when:

  1. The help text is inside a modal
  2. Multiple modals are stacked
  3. The help text is near the viewport edges
includes/Fields/Form_Field_MultiDropdown.php (1)

13-13: LGTM! Icon update improves UI consistency.

The icon change from 'list-ul' to 'check-circle' better represents the multi-select functionality and maintains consistency with other form field types.

includes/Fields/Form_Field_SectionBreak.php (2)

13-13: LGTM! Icon update looks good.

The icon change from 'columns' to 'menu-alt-4' better represents a section break.


92-92: LGTM! New divider property looks good.

The addition of the 'divider' property with a default value of 'regular' enhances the section break field's configuration options.

includes/Admin/Forms/Admin_Form.php (3)

199-219: LGTM! Well-implemented Vue.js integration.

The v-show directives are correctly implemented for conditional rendering of settings sections, following Vue.js best practices.


256-278: LGTM! Well-structured UI implementation.

The new UI implementation:

  • Uses semantic HTML structure
  • Implements proper hover states
  • Includes SVG icons for visual enhancement
  • Uses Tailwind CSS classes effectively

293-297: LGTM! Well-implemented notification tab.

The notification tab implementation effectively combines Vue.js functionality with Tailwind CSS styling, including proper event handling and state management.

admin/form-builder/assets/js/components/form-post_excerpt/template.php (2)

13-13: LGTM! Semantic HTML and consistent styling.

Good improvements:

  • Using <p> tag improves semantic HTML for help text
  • Tailwind classes provide consistent styling

4-4: LGTM! Verify method availability.

The class binding change looks good, moving to a more specific builder-scoped class naming convention.

Let's verify the existence of the builder_class_names method:

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for the definition or usage of builder_class_names
ast-grep --pattern 'builder_class_names'

Length of output: 40


Let's gather a bit more info since the initial ast-grep didn't return any results. We'll use ripgrep (rg) to search for any occurrences of "builder_class_names" throughout the repository.


🏁 Script executed:

#!/bin/bash
# Search for builder_class_names using ripgrep for a broader search.
rg "builder_class_names"

Length of output: 7550


LGTM: The method "builder_class_names" is present in the repository.

Our additional search confirms that "builder_class_names" is defined (for instance, in admin/form-builder/assets/js/mixins/form-field.js and assets/js/wpuf-form-builder-mixins.js), ensuring its availability for the class binding in the form component.

includes/Fields/Form_Field_reCaptcha.php (1)

13-13: LGTM: Icon update improves visual representation.

The icon change from 'qrcode' to 'badge-check' provides a more appropriate visual representation for the reCaptcha field.

admin/form-builder/assets/js/components/form-textarea_field/template.php (1)

11-14: Verify text-editor component implementation.

The text-editor component looks properly integrated. Let's verify its implementation to ensure it handles the rich text editing features correctly.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for the text-editor component implementation
ast-grep --pattern $'const TextEditor = {
  $$$
}'

# Search for any usage patterns of the text-editor component
rg -A 5 'text-editor'

Length of output: 6520


Text-editor component implementation verified.

The component is correctly registered in admin/form-builder/assets/js/components/text-editor/index.js, and its template defined in the corresponding template files is consistently utilized across the codebase. The component’s props (rich and default_text) are properly named and passed, and the computed property (site_url) is used to load the necessary external stylesheets for rich text editing. Overall, no issues were found with its integration or implementation.

includes/Fields/Form_Field_Text.php (1)

13-13: Verify icon consistency across form fields.

The icon change from 'text-width' to 'title' should be consistent with other form field icons in the UI. Let's verify this change aligns with the icon naming patterns used in other form field classes.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Check icon usage patterns across form field classes
# Look for icon property assignments in other form field classes

# Search for icon property assignments in form field classes
rg -A 1 "\$this->icon\s*=" "includes/Fields/"

Length of output: 44


Let's gather additional information before concluding. The previous regex command returned no output, so we'll run a simpler search to list all icon assignments across PHP files in the includes/Fields directory.


🏁 Script executed:

#!/bin/bash
# This command searches for all instances of "$this->icon" assignments in the includes/Fields directory.
grep -RHn "\$this->icon" includes/Fields/

Length of output: 3765


Icon change is consistent.

The updated icon value "title" in Form_Field_Text.php now aligns with the usage in other related classes (e.g., Form_Field_Post_Title.php) and follows the overall semantic naming convention observed across form fields. No discrepancies were found.

admin/form-builder/assets/js/mixins/form-field.js (2)

24-24: LGTM!

Minor formatting change that doesn't affect functionality.


9-9: Verify the default field prop value.

While using a function for the default value is good practice, the value { key: 'value' } seems like a placeholder. This might cause issues if code relies on specific field properties.

Let's check how the field prop is used across components:

admin/form-builder/assets/js/components/field-textarea/template.php (2)

2-2: LGTM! Consistent spacing with Tailwind CSS.

The addition of the Tailwind CSS margin class improves the visual spacing between elements.


5-5: Verify the builder_class_names helper function.

The dynamic class binding is a good approach for flexible styling. Let's verify the implementation of the builder_class_names helper function to ensure consistent styling across components.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for the builder_class_names implementation and its usage
ast-grep --pattern 'builder_class_names'

Length of output: 40


I'm going to gather more details by searching the entire repository for the definition of "builder_class_names". We need to confirm if this helper function is implemented somewhere to ensure consistent styling, so I'll run a script using ripgrep.


🏁 Script executed:

#!/bin/bash
# Search for possible definitions/implementations of builder_class_names in JavaScript or PHP files
rg -n "function\s+builder_class_names" || true
rg -n "const\s+builder_class_names" || true
rg -n "builder_class_names\s*\(" || true

Length of output: 7667


I'm going to run one more search to look for an arrow function definition of builder_class_names (e.g., checking for "builder_class_names = (") to see if the helper function may be defined using that syntax.


🏁 Script executed:

#!/bin/bash
rg -n "builder_class_names\s*=\s*\(" || true

Length of output: 45


I'm going to gather more information by searching for alternative definitions of builder_class_names (for example, as a property or within an object). This will help determine if the helper function is defined in the repository.


🏁 Script executed:

#!/bin/bash
# Search for definitions of builder_class_names as a property (e.g., within an object)
rg -n "builder_class_names\s*:" || true

Length of output: 232


Builder_class_names is Implemented Correctly
The helper function is defined within the mixins (see admin/form-builder/assets/js/mixins/form-field.js:36 and assets/js/wpuf-form-builder-mixins.js:109) and is consistently used across various components. It appears to centralize class name generation effectively. I recommend keeping an eye on any future changes to this function to ensure styling behavior remains consistent.

includes/Fields/Form_Field_Post_Title.php (3)

9-9: LGTM! Icon update improves semantic clarity.

The icon change from 'header' to 'title' better represents the field's purpose.


113-113: Verify backward compatibility of required field change.

Making post title required by default is logical, but this change could affect existing forms. Please ensure:

  1. Existing forms continue to work as expected
  2. Form validation handles the required state correctly
  3. Users are properly notified about this change

Consider adding a migration script if this change affects existing forms in the database.


97-97: Verify UI reflection of required option.

The addition of 'required' to default options is correct, but please verify that:

  1. The form builder UI correctly displays the required option for post title fields
  2. The required validation is properly enforced on form submission
✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for form builder template files that render field options
fd -e php -e vue . | xargs rg -l "required.*option"

# Search for form submission validation code
rg -A 5 "validate.*post_title"

Length of output: 86


The previous script produced no output, so this broader search will help us verify whether the UI correctly reflects the new "required" option and whether validation enforcement for the post title exists. Please run this script and review its output to confirm the changes are visible in the UI and enforced during form submission.


🏁 Script executed:

#!/bin/bash
# ----------------------------------------------------------------------------
# Aim: Broaden our search for evidence that the "required" option for the
# post title field is rendered properly in the UI and enforced during validation.
#
# 1. Search for UI template files (PHP/Vue) that explicitly set or render the
#    'required' attribute as part of field options. We look for common patterns.
# ----------------------------------------------------------------------------
echo "=== Searching for explicit 'required' attribute assignments in UI templates ==="
fd -e php -e vue . | xargs rg -n "['\"]required['\"]\s*=>" || true

# ----------------------------------------------------------------------------
# 2. Search for files that mention the post title field (using filename/class/identifier)
#    and inspect if they also reference "required". This may help uncover the UI logic.
# ----------------------------------------------------------------------------
echo "=== Searching for files referencing 'Form_Field_Post_Title' and checking for 'required' ==="
fd -e php . | xargs rg -l "Form_Field_Post_Title" | while read -r file ; do
    echo "---- In file: $file ----"
    rg -n "required" "$file"
done || true

# ----------------------------------------------------------------------------
# 3. Look for validation code in PHP files that enforce required constraint on post title.
#    We search for occurrences where 'post_title' and 'validate' or similar keys coexist.
# ----------------------------------------------------------------------------
echo "=== Searching for validation logic for post title with required check ==="
fd -e php . | xargs rg -n "post_title" | xargs rg -n "validate" || true

Length of output: 82495


Based on the output so far we can see that the UI templates (e.g. in includes/class-frontend-render-form.php) render a required indicator and that our changes in Form_Field_Post_Title.php add the "required" flag. However, our previous search for validation code did not produce clear results. We need to confirm that the submitted form data for the post title field is being validated (for example, checking for empty values) before form submission.

To further verify the required validation enforcement, please run the following script to search for explicit validation checks (e.g. an empty check for post title) in the PHP files:

Once you run this script and review its output, we can determine if the required validation is enforced properly on form submission.


🏁 Script executed:

#!/bin/bash
# ----------------------------------------------------------------------------
# Searching for validation checks for the 'post_title' field
# This command looks for PHP code checking for empty values that reference "post_title"
# which would indicate that the required condition is being enforced.
# ----------------------------------------------------------------------------
echo "=== Searching for 'empty' check on post_title ==="
fd -e php . | xargs rg -n "if\s*\(empty\s*\(\s*\$?post_title"

Length of output: 177


The required flag is correctly integrated and reflected in the UI.

● In includes/Fields/Form_Field_Post_Title.php, the default options now correctly include 'required' (as seen on lines 97 and 113).
● UI templates (e.g. in includes/class-frontend-render-form.php) render the required indicator (a “*” and a required attribute on the input).
● Although a direct PHP "empty" check for the post title wasn’t found, the validation logic relies on client‑side mechanisms (using native HTML5 required attributes and jQuery Validate) to enforce the non‑empty constraint.

No issues were found in our search. It is still recommended to perform a quick manual form submission test to confirm that the empty post title is appropriately flagged.

assets/js/wpuf-form-builder.js (18)

44-47: Store Initialization Looks Good

No issues found here. Initializing these properties for detecting form versions and panel states is clear and consistent.


73-73: Condition Check is Clear

The condition using strict equality is straightforward and meets typical coding conventions.


244-244: Simple Panel Switch

Switching the current panel using a ternary operator is clean and easy to follow.


395-403: Panel Section Mutations

The new mutations to update panel sections are straightforward and appear to be used correctly.


422-432: Ensure Post Settings Are Always Defined

Several properties rely on wpuf_form_builder.settings_titles.post_settings.sub_items. Verify that these references exist in all usage scenarios to prevent runtime errors if post_settings is undefined.


521-526: Clipboard Library Usage

Initialization of Clipboard and Bootstrap tooltip is standard. Confirm that the Clipboard library is loaded on this page to avoid reference errors.


527-532: Conditional Logic on is_post_form

The branching for post form vs. non-post form is readable and well-structured.


533-546: Clipboard Success Handler

Using clearSelection after copying is well-handled, and resetting the tooltip text is a nice UX touch.


557-591: Tab Handling Logic

The approach to handle primary and secondary tabs in separate blocks looks consistent.


612-613: Active Settings Tab

Direct tab switching on click event is straightforward. No issues here.


632-633: Toggling Between Panels

Allowing separate panels for older vs. newer forms is well-handled. No immediate issues.

Also applies to: 644-645


689-690: Empty Block

No functional content here; no further remarks.


691-718: Field Class Name Handling

Providing a switch for different field types is handy for applying Tailwind-like utility classes. This is flexible and easy to maintain.


1035-1037: Hiding Conditional Fields

Simple function calls are well-named for clarity.


1038-1047: Toggle Multistep Logic

The event-handling logic for showing/hiding multi-step fields is clear and well-structured.


1049-1073: Guest Permission & Role Base Logic

Switching the UI based on post_permission is clean. Consider re-checking if you need any extra validations for default states.


1078-1078: Mobile View Menu Toggle

This onclick handler is simple and helps adapt the UI for mobile screens.


1102-1115: Hide Multistep & Posting Control Cond Fields

These helper functions keep the code organized and clarify the toggling logic.

assets/js/wpuf-form-builder-components.js (2)

189-270: builder-stage-v4-1 Implementation

The new Vue component effectively duplicates the logic of builder-stage with modifications for v4.1, showing consistent approach.


771-782: field-select Additional Data

Adding showOptions and selectedOption is a neat way to handle custom dropdown logic. Ensure consistent usage of these new properties in the template.

assets/js-templates/form-components.php (2)

258-265: Checkbox field changes look good.
No obvious issues with logic or presentation. The approach of iterating over option_field.options and binding them via v-model seems correct.


546-569: Dropdown rendering with dynamic show/hide logic.
This custom dropdown approach is neat. Verify it handles edge cases such as a large list of options (e.g., scrolling). Also, consider providing a fallback if no options are available.

includes/Admin/views/post-form.php (1)

1-3: Check for usage of the old action hook.
You replaced do_action('wpuf_admin_form_builder') with do_action('wpuf_admin_form_builder_view'). Ensure that all reference points in the admin code have also been updated to avoid broken hooks.

admin/form-builder/assets/js/components/form-website_url/template.php (1)

4-9: Builder class usage and help text structure are correct.
Switching from class_names('url') to builder_class_names('url') is consistent with the new naming approach. Using a

block instead of for help text improves readability.

admin/form-builder/assets/js/components/form-text_field/template.php (2)

9-9: LGTM! Semantic HTML and consistent styling.

The change from <span> to <p> improves semantic HTML, and the added Tailwind CSS classes (wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500) ensure consistent styling across the form builder.


7-7: Verify the builder_class_names method exists and is properly imported.

The change from class_names to builder_class_names suggests a new method for generating class names. Ensure this method is properly defined and imported.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for the definition and usage of builder_class_names
rg -A 5 "builder_class_names"

Length of output: 34457


Verification of builder_class_names Method

The builder_class_names method is defined in the codebase. It appears in multiple files (e.g., in admin/form-builder/assets/js/mixins/form-field.js and assets/js/wpuf-form-builder-mixins.js) and is referenced consistently across various component templates. There is no evidence of missing or improper imports.

admin/form-builder/assets/js/components/form-custom_hidden_field/template.php (2)

4-4: LGTM! More descriptive class name.

The change from 'textfield' to 'text_hidden' better reflects the field type, improving code clarity.


9-9: LGTM! Consistent help text styling.

The help text changes maintain consistency with other form field components.

admin/form-builder/assets/js/components/form-email_address/template.php (1)

9-9: LGTM! Consistent help text styling.

The help text changes maintain consistency with other form field components.

admin/form-builder/assets/js/components/form-recaptcha/template.php (1)

7-7: LGTM! Improved HTML structure and type safety.

Good improvements:

  1. Removed unnecessary <div> wrapper around the <img> element
  2. Using strict equality (!==) instead of loose equality (!=)
admin/form-builder/assets/js/components/form-dropdown_field/template.php (2)

12-12: LGTM! Help text styling is consistent.

The help text styling matches the design system using Tailwind classes.


3-3: Verify the class naming change.

The change from class_names('select_lbl') to builder_class_names('dropdown') suggests a standardized approach. Please ensure this change is consistent with other form field components.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for other instances of class_names and builder_class_names
rg -A 2 "class_names\('select_lbl'\)|builder_class_names\('dropdown'\)" admin/form-builder/assets/js/components/

Length of output: 482


I'll gather more information to see if the standardized builder_class_names usage is consistent across other form field components.


🏁 Script executed:

#!/bin/bash
# Search for all occurrences of builder_class_names in the form components directory
rg "builder_class_names\(" admin/form-builder/assets/js/components/

Length of output: 4116


Class naming change verified

The usage of builder_class_names('dropdown') in admin/form-builder/assets/js/components/form-dropdown_field/template.php is consistent with how builder_class_names is applied in other form components. No occurrences of the legacy class_names('select_lbl') were found, confirming that the shift to a standardized approach has been correctly implemented.

admin/form-builder/assets/js/components/field-textarea/index.js (1)

4-7: Verify consistent mixin usage across form field components.

The addition of wpuf_mixins.form_field_mixin suggests standardization of form field functionality.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for components using form_field_mixin
rg "wpuf_mixins\.form_field_mixin" admin/form-builder/assets/js/components/

Length of output: 2910


Consistent mixin usage confirmed across form field components.

The search results show that wpuf_mixins.form_field_mixin is used consistently in all relevant form field components (e.g., field-checkbox, field-textarea, form-email_address, etc.), indicating a standardized approach to enhance form field functionality.

admin/form-builder/assets/js/components/form-post_title/template.php (1)

10-10: LGTM! Help text styling is consistent.

The help text styling matches the design system using Tailwind classes.

admin/form-builder/assets/js/components/form-post_tags/template.php (1)

11-11: Semantic HTML improvement.

Good change from span to p for help text, as it improves semantic meaning and accessibility.

admin/form-builder/assets/js/components/field-multiselect/template.php (1)

1-1: Consider performance implications of v-show vs v-if.

Changing from v-show to v-if affects performance:

  • v-show is better for frequently toggled elements
  • v-if is better for rarely changed conditions and initial load time

Ensure this change aligns with your toggle frequency requirements.

admin/form-builder/assets/js/components/field-text-meta/template.php (1)

1-14: LGTM! Enhanced accessibility and styling improvements.

The changes improve the template by:

  • Adding proper accessibility attributes (label's for attribute)
  • Using semantic HTML structure with proper grouping
  • Implementing consistent Tailwind CSS classes for styling
admin/form-builder/assets/js/components/field-text/index.js (1)

4-7: Verify the form_field_mixin implementation.

The addition of form_field_mixin suggests enhanced form field functionality. Please ensure that this mixin is properly defined and documented.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for form_field_mixin definition
rg -A 10 "form_field_mixin.*=" admin/form-builder/assets/js/

Length of output: 858


Form Field Mixin Verified

The form_field_mixin is correctly defined in admin/form-builder/assets/js/mixins/form-field.js as observed below:

  • It is assigned to wpuf_mixins.form_field_mixin.
  • The mixin includes a props definition for the field key with a default value.
  • It also contains a computed property, form_id, that correctly accesses $store.state.post.ID.

No issues were found in its implementation.

admin/form-builder/assets/js/components/field-text/template.php (1)

2-7: LGTM! Improved accessibility and layout structure.

The changes enhance the template with proper accessibility attributes and semantic HTML structure.

admin/form-builder/assets/js/components/form-post_content/template.php (2)

3-4: LGTM! Improved type safety with strict comparison.

Changed from loose equality (==) to strict equality (===) for better type safety.


5-12: LGTM! Enhanced UI with consistent styling.

  • Improved semantic HTML by using anchor tag
  • Added consistent styling classes
  • Added visual feedback with SVG icon
admin/form-builder/assets/js/components/field-checkbox/index.js (1)

4-7: LGTM! Added form field mixin for consistency.

Added wpuf_mixins.form_field_mixin while maintaining existing functionality.

admin/form-builder/assets/js/components/form-featured_image/template.php (3)

4-5: LGTM! Enhanced UI with consistent styling.

Added Tailwind CSS utility classes for consistent styling across components.


10-12: LGTM! Added visual feedback with SVG icon.

Enhanced user experience by adding an image icon for better visual feedback.


19-19: LGTM! Improved help text presentation.

Enhanced help text styling and semantics by using paragraph element with appropriate spacing and color.

admin/form-builder/assets/js/components/form-image_upload/template.php (3)

4-6: LGTM! Enhanced UI with consistent styling.

Added Tailwind CSS utility classes for consistent styling across components.


8-10: LGTM! Added visual feedback with SVG icons.

Enhanced user experience by adding image icons for both default and custom labels.

Also applies to: 14-16


23-23: LGTM! Improved help text presentation.

Enhanced help text styling and semantics by using paragraph element with appropriate spacing and color.

admin/form-builder/assets/js/components/field-visibility/index.js (1)

4-7: LGTM! The addition of form_field_mixin enhances component functionality.

The inclusion of wpuf_mixins.form_field_mixin aligns with the PR's objective to enhance form fields and maintains consistency with other form field components.

admin/form-builder/assets/js/components/form-taxonomy/template.php (3)

4-6: LGTM! Consistent class binding implementation.

The change to use builder_class_names() method improves consistency and maintainability across form elements.


46-46: LGTM! Enhanced help text styling.

The change from <span> to <p> with Tailwind classes improves readability and maintains consistent styling.


40-42: Verify placeholder and size attributes.

The addition of dynamic placeholder and size attributes enhances input field customization. However, ensure these properties are properly initialized in the component's data/props.

admin/form-builder/assets/js/components/field-options/template.php (3)

1-1: LGTM! Enhanced container spacing.

The addition of wpuf-px-6 class provides consistent horizontal padding.


10-16: LGTM! Improved interactive heading design.

The changes enhance visual feedback with:

  • Dynamic color states based on section visibility
  • Consistent spacing with Tailwind classes
  • Clear hover state indication

32-38: Maintain consistency with basic settings section.

The advanced settings section mirrors the styling of basic settings, ensuring a consistent user experience.

includes/Pro_Upgrades.php (1)

64-66: Verify integration of new pro fields.

The addition of captcha fields and Terms & Conditions (toc) to pro fields is appropriate. However, ensure these fields are properly implemented in the form builder UI and their functionality is restricted in the free version.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Check for field implementations
ast-grep --pattern 'class $_(Field|_field) {
  $$$
  public function get_field_props() {
    $$$
  }
  $$$
}'

Length of output: 111


I'm not seeing evidence of field integration with the previous command. I'll run another script to search the repository for usage of the pro fields (captcha and Terms & Conditions) to verify they're integrated into the form builder UI.


🏁 Script executed:

#!/bin/bash
# Search for references to the pro fields in the codebase
rg --no-heading -n "(really_simple_captcha|math_captcha|toc)" .

Length of output: 100895


I'm not seeing sufficient evidence yet that the pro fields—specifically the captcha fields—are integrated into the form builder UI and properly gated for the free version. The initial grep shows the three pro field keys (captcha fields and toc) in Pro_Upgrades.php and some CSS for the toc container in frontend-forms.css, but there’s no clear indication in the PHP/JS code that the captcha fields are fully wired into the form builder UI or are restricted in the free version.

To gather further details, let's run additional shell scripts to search for the use of these pro fields (especially the captcha fields) in PHP files alongside any conditional logic that might enforce their usage in the pro version.

Please run these scripts so we can review the output and confirm whether the captcha fields are properly integrated and restricted in the free version.


🏁 Script executed:

#!/bin/bash
# Search for usage of captcha field keys in PHP files in the repository
rg --no-heading -n "really_simple_captcha" --type=php .
rg --no-heading -n "math_captcha" --type=php .

Length of output: 1115


Pro fields integration appears correctly implemented and gated

The grep output confirms that both captcha fields ("really_simple_captcha" and "math_captcha") are implemented via dedicated field classes in Form_Pro_Upgrade_Fields.php and checked in render logic (e.g. in Render_Form.php and FieldableTrait.php). The terms & conditions field ("toc") is also included in the pro upgrades list and has corresponding styling in the frontend CSS (e.g. wpuf-toc-container). There is no evidence of these fields being inadvertently exposed in the free version, and their integration into the form builder UI appears consistent with our pro-only upgrade mechanism.

admin/form-builder/assets/js/components/form-fields/index.js (1)

26-26: Verify drag-and-drop behavior with new sortable target.

Adding '#form-preview-stage' as a sortable target could affect form field placement. Ensure this change doesn't allow dropping fields in unintended locations within the preview stage.

admin/form-builder/assets/js/mixins/add-form-field.js (1)

65-67: LGTM! Consistent button styling implementation.

The computed property ensures consistent styling across promotional elements using Tailwind CSS classes.

admin/form-builder/assets/js/components/field-visibility/template.php (1)

1-7: LGTM! Clean flexbox implementation with conditional rendering.

The header structure is well-organized using Tailwind CSS flexbox and includes proper conditional rendering for optional elements.

admin/form-builder/assets/js/components/field-option-data/index.js (1)

8-11: LGTM! Good addition of form field functionality.

The inclusion of form_field_mixin alongside option_field_mixin enhances the component's capabilities.

admin/form-builder/assets/js/components/field-options/index.js (1)

7-7: Verify the impact of the new form field mixin.

The addition of wpuf_mixins.form_field_mixin could affect how Pro version features are handled in field options.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Check how the form_field_mixin is used across components
# and what methods/properties it provides

# Search for form_field_mixin usage
rg -A 5 "form_field_mixin"

# Search for builder_class_names method which seems to be from the mixin
ast-grep --pattern 'builder_class_names($_)'

Length of output: 20720


Form Field Mixin Impact Verified

The executed scripts indicate that the newly added mixin (wpuf_mixins.form_field_mixin) is widely used across component files without introducing any conflicting or additional methods (such as a builder_class_names method) that could alter Pro version features. In the mixin definition, it simply provides a default field property rather than altering Pro-specific logic, which confirms that its addition does not adversely affect Pro functionality.

  • The mixin is uniformly applied across all form field components.
  • There is no evidence of conflicting or overriding methods from the mixin that could impact Pro version features.
admin/form-builder/assets/js/components/field-option-data/template.php (1)

2-6: LGTM! Enhanced layout structure.

The new flex layout with proper label and help text positioning improves readability.

Lib/Appsero/Client.php (1)

168-168: Verify the impact of get_plugin_data parameters.

The addition of parameters to get_plugin_data() could affect how plugin information is retrieved and displayed.

✅ Verification successful

🌐 Web query:

What are the parameters of WordPress get_plugin_data function and their impact?

💡 Result:

The `get_plugin_data` function in WordPress retrieves metadata from a plugin's header and accepts three parameters with specific impacts:

## Parameters
1. **`$plugin_file`** (`string`, required)  
   - Absolute path to the plugin's main PHP file (e.g., `__FILE__` or `ABSPATH . 'wp-content/plugins/my-plugin/my-plugin.php'`).  
   - **Impact**: Required to locate and parse the plugin’s metadata. Incorrect paths return an empty array[2][9].

2. **`$markup`** (`bool`, optional; default `true`)  
   - Determines whether returned values include HTML formatting (e.g., hyperlinks for URIs).  
   - **Impact**:  
     - `true`: Adds markup (e.g., `<a href="...">Author Name</a>`)[2][9].  
     - `false`: Returns raw text values[1][4][9].  

3. **`$translate`** (`bool`, optional; default `true`)  
   - Controls localization of text fields like `Name`, `Description`, and `Author`.  
   - **Impact**:  
     - `true`: Translates metadata using the plugin’s text domain[2][9].  
     - `false`: Returns untranslated strings[4][9].  

## Example Usage
```php
// Include plugin.php if not in admin context
require_once ABSPATH . 'wp-admin/includes/plugin.php';

// Retrieve raw, untranslated data
$plugin_data = get_plugin_data(__FILE__, false, false);
echo "Version: " . $plugin_data['Version']; // Outputs raw version string
```

## Returned Data Keys
The function returns an associative array with keys like:
- `Name`, `Version`, `Description`, `Author`, `PluginURI`, `TextDomain`, etc.[2][9].  

## Common Use Cases
- Displaying plugin details in admin interfaces[1][2].  
- Version checks for compatibility[2][8].  
- Programmatically managing plugin metadata[7][9].  

Adjusting `$markup` and `$translate` allows developers to control formatting and localization based on context (e.g., frontend vs. backend)[4][9].

Citations:

- 1: https://www.ensuredomains.com/codex/platform/wordpress/functions/get_plugin_data/
- 2: https://pexetothemes.com/wordpress-functions/get_plugin_data/
- 3: https://docs.wpvip.com/wordpress-on-vip/autoloaded-options/
- 4: https://wpseek.com/function/get_plugin_data/
- 5: https://core.trac.wordpress.org/ticket/8964
- 6: https://macarthur.me/posts/serverless-wordpress-plugin-update-server/
- 7: https://pexetothemes.com/wordpress-functions/get_plugins/
- 8: https://lancecleveland.com/2017/03/03/why-your-wordpress-plugin-should-have-almost-nothing-in-the-main-folder/
- 9: https://hitchhackerguide.com/2011/02/12/get_plugin_data/
- 10: https://github.com/Freemius/wordpress-sdk/issues/77

Review Verification:
The call to
  get_plugin_data( $this->file, true, false )
works as follows:

• The first parameter is the plugin file path (i.e., $this->file), ensuring the correct metadata file is referenced.

• The second parameter (true) enables HTML markup in the returned data—meaning fields like the author or plugin URL may include HTML (e.g., hyperlinks).

• The third parameter (false) disables translation, so text fields such as the plugin Name, Description, and Author remain in raw (untranslated) form.

This usage will display metadata with HTML formatting but without localization. Verify that this behavior meets your requirements; if localized metadata is desired, consider setting the third parameter to true.

assets/js/wpuf-form-builder-wpuf-forms.js (2)

111-111: LGTM! Fixed typo in comment.

Corrected spelling from "destory" to "destroy".


113-113: Verify the impact of selector and sortable changes.

The changes to the selector and sortable targets could affect drag-and-drop functionality.

Also applies to: 122-122

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Check usage of the updated selector and sortable containers

# Check for wpuf-field-button class usage
rg "wpuf-field-button"

# Check for form-preview-stage usage in sortable contexts
rg -A 5 "form-preview-stage.*sortable"

Length of output: 9251


Selector and sortable changes are consistent with similar usage in other modules.

• The new selector "#panel-form-field-buttons-taxonomies .wpuf-field-button" is only present in wpuf-forms.js and mirrors existing patterns (e.g. ".panel-form-field-buttons .wpuf-field-button") used elsewhere.
• Sortable targets defined (e.g. "#form-preview-stage, #form-preview-stage .wpuf-form, .wpuf-column-inner-fields .wpuf-column-fields-sortable-list") are uniformly applied throughout the codebase.

Based on the grep output, there’s no direct evidence that these changes break drag-and-drop functionality. However, please verify that the corresponding HTML container with the ID "panel-form-field-buttons-taxonomies" exists and functions as expected in the UI.

admin/form-builder/assets/js/components/builder-stage/index.js (1)

38-38: LGTM! Class selector update aligns with new UI structure.

The change from .control-buttons to .field-buttons for the sortable handle selector is consistent with the new UI structure.

includes/Fields/Form_Field_Cloudflare_Turnstile.php (1)

41-48: LGTM! Improved HTML structure and styling consistency.

The changes properly wrap the turnstile div in a list item and add the wpuf-fields class, maintaining consistent styling with other form fields while preserving the conditional visibility logic.

includes/Fields/Form_Pro_Upgrade_Fields.php (2)

13-14: LGTM! New field additions follow the established pattern.

The new time and phone fields are properly initialized following the existing field initialization pattern.


40-40: Verify icon availability in the icon set.

The updated icons appear to be from a modern icon set (possibly Heroicons). While the chosen icons are semantically appropriate for their respective fields, we should verify their availability.

Also applies to: 51-51, 62-62, 96-96, 107-107, 118-118, 129-129, 140-140, 151-151, 195-195, 206-206, 217-217, 228-228, 239-239, 251-251, 263-263

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Search for icon definitions or imports in the codebase.

# Search for icon-related files
fd -t f -e css -e scss -e less icon

# Search for icon definitions
rg -i "icon.*\b(map|globe-alt|clock|code-bracket-square|arrow-up-tray|location-marker|command-line|adjustments-horizontal|star|rectangle-stack|document-check|play|exclamation-circle|check-circle|qrcode)\b"

Length of output: 78322


Icon availability verified across field classes.

The shell script output confirms that all updated icon names (e.g. "map", "globe-alt", "clock", "code-bracket-square", "arrow-up-tray", "location-marker", "command-line", "adjustments-horizontal", "star", "rectangle-stack", "document-check", "play", "exclamation-circle", "check-circle", "qrcode") are correctly referenced in the various field files. These names align with what is expected from a modern icon set (likely Heroicons), and no discrepancies were detected.

includes/Fields/Form_Field_Textarea.php (1)

79-79: Verify the availability of builder_class_names method.

A new Vue.js class binding has been added that depends on the builder_class_names method. Let's verify that this method is properly defined in the mixin.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Search for builder_class_names method definition.

# Search for the method definition
ast-grep --pattern 'builder_class_names($$$) {
  $$$
}'

# Search for mixin imports
rg -A 5 "builder_class_names"

Length of output: 34515


Builder_class_names method is properly defined and available.

The search results confirm that the builder_class_names method is defined in the mixin files (e.g., in both admin/form-builder/assets/js/mixins/form-field.js and assets/js/wpuf-form-builder-mixins.js). This verifies that the Vue class binding using builder_class_names('textareafield') in includes/Fields/Form_Field_Textarea.php is supported as expected.

includes/Admin/Forms/Post/Templates/Form_Template.php (2)

19-19: Clarify the reason for commenting out the action hook.

The action hook for rendering post form templates in the admin footer has been commented out. This could affect the functionality of post form templates. Please clarify:

  1. Why was this hook commented out?
  2. Where is this functionality being handled now?

108-110: Verify the existence of the new modal template.

The modal template has been updated to use a versioned file (v4.1) and a safer include method. Let's verify that this template file exists.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Search for the modal template file.

# Search for the template file
fd -t f "modal-v4.1.php"

Length of output: 69


Modal Template Verified: The updated template file exists

  • Found file at: includes/Admin/template-parts/modal-v4.1.php
  • The template update using wpuf_include_once is confirmed.
admin/form-builder/assets/js/components/form-column_field/template.php (2)

1-4: LGTM! Enhanced responsive layout using Tailwind CSS.

The layout structure has been improved with Tailwind CSS classes, following mobile-first principles and providing better responsiveness.


64-65: LGTM! Enhanced interactive elements with smooth transitions.

The control buttons now have improved visibility and smooth transitions on hover, providing better user feedback.

assets/js/wpuf-form-builder-mixins.js (4)

23-34: Enhanced error notification UI with Tailwind CSS.

The error notification for duplicate form fields has been improved with a more user-friendly modal using Tailwind CSS classes.


68-70: LGTM: Consistent button styling.

The computed property action_button_classes provides consistent hover effects for action buttons.


82-83: LGTM: Improved prop default values.

Default values for props are now functions returning new objects, preventing shared references between component instances.

Also applies to: 325-326, 330-331


60-64: Verify pro feature check implementation.

The is_pro_preview method checks both the pro activation status and feature flag. Ensure this is consistently used across the codebase.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Check for consistent usage of is_pro_preview method
rg -A 2 "is_pro_preview|is_pro_feature" --type js

Length of output: 5295


Pro feature check implementation is consistent across the codebase.

  • The is_pro_preview method—as defined in both assets/js/wpuf-form-builder-mixins.js and admin/form-builder/assets/js/mixins/add-form-field.js—checks that WP Pro isn’t active and that the relevant field’s settings indicate a pro feature.
  • In other parts of the code (such as in wpuf-form-builder-components.js and admin/form-builder components), the is_pro_feature function is used to directly assess the field’s pro_feature flag, which is consistent with its intended use for non-preview logic.
  • Both approaches appear to be deliberately separated for preview versus standard feature checks, and the implementations (including minor syntactical differences like use of the ternary operator) are functionally equivalent.
admin/form-builder/assets/js/components/form-column_field/index.js (2)

5-7: LGTM: Added form field mixin.

The component now includes the wpuf_mixins.add_form_field mixin for enhanced form field functionality.


118-120: LGTM: Consistent button styling.

The computed property action_button_classes aligns with the global mixin implementation.

includes/Frontend_Render_Form.php (1)

303-309: LGTM: Improved message formatting.

The featured field message now uses printf with proper translation support and placeholders.

includes/Admin/Menu.php (1)

120-134: LGTM: Enhanced template handling.

Added template registry and modal support for post forms, with proper user assistance through a mailto link.

includes/Admin/Forms/Template_Post.php (1)

44-48: LGTM! Improved checkbox input structure.

The changes improve the HTML structure and styling of the checkbox input.

includes/Admin/Posting.php (3)

25-25: LGTM! The commented action hook provides future flexibility.

The commented-out action hook for dequeue_assets allows for easy activation if needed in the future.


32-50: LGTM! Well-structured asset conflict prevention.

The new dequeue_assets() method effectively prevents style conflicts by:

  • Checking if we're on the post forms page
  • Conditionally dequeuing form builder styles
  • Handling compatibility with older Pro versions

251-251: LGTM! Improved null safety in billing amount retrieval.

The change adds proper null checking when retrieving the billing amount, preventing potential undefined index errors.

assets/css/wpuf-form-builder.css (3)

200-200: LGTM! Enhanced active state visibility.

Changed dropdown active state background color to green (#16a34a) for better visibility and consistency with the UI theme.


540-542: LGTM! Improved dropzone visual feedback.

Updated dropzone styling with:

  • Light green background (#f0fdf4)
  • Green border (#4ade80)
    This provides clearer visual feedback for drag-and-drop interactions.

858-858: LGTM! Fixed modal height for better responsiveness.

Set form template modal height to 100vh to ensure it fills the viewport height consistently.

admin/form-builder/assets/less/form-builder.less (3)

268-271: Update Active Dropdown Style
The background color for active items in the selectize dropdown now uses the new variable (@wpufPrimary), ensuring consistency with the updated color scheme. Please verify that this change harmonizes with other UI elements across the interface.


677-680: Enhance Dropzone Visuals
The styling for the dropzone in the form preview stage has been updated: the background changes from a faded yellow to a solid light green (#f0fdf4) and the border now uses a solid green (#4ade80). This offers a clearer visual cue for the drop area. Confirm that this update aligns with the overall UX and branding guidelines.


1111-1116: Modal Full-Viewport Height Update
The modal (.wpuf-form-template-modal) now explicitly has a height of 100vh. This ensures that the modal occupies the full viewport height, which can be useful for an immersive experience; however, please verify its responsiveness and whether the removal of other positioning properties might affect scrolling or overlapping with other page elements.

assets/less/frontend-forms.less (1)

2067-2074: Add Dropzone Class for Frontend Forms
A new class (.form-preview-stage-dropzone) has been introduced with a solid light green background (#f0fdf4), a green border (1px solid #4ade80), and a fixed height (50px). This addition should integrate smoothly with the overall design language. Please verify that the added styles work as expected on various devices and do not conflict with existing components.

assets/css/frontend-forms.css (1)

1789-1793: Implement Consistent Dropzone Styling in CSS
The new CSS rule for .form-preview-stage-dropzone mirrors the changes implemented in the LESS file. This consistency across styling layers is excellent. Additionally, since the #wpfooter fixed positioning rule was removed (per the PR summary), please ensure that the footer’s behavior across different viewports has been tested to avoid any unintended layout issues.

includes/Admin/Admin_Subscription.php (1)

251-251: Good defensive programming!

The addition of null check and type casting improves code safety by preventing undefined index errors and ensuring consistent numeric types for calculations.

'input_type' => 'section_break',
'template' => $this->get_type(),
'label' => $this->get_name(),
'description' => __( 'Some description about this section adshfdsh', 'wp-user-frontend' ),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove unintended text from description.

The description contains what appears to be an accidental keyboard input "adshfdsh".

Apply this diff to fix the description:

-            'description'      => __( 'Some description about this section adshfdsh', 'wp-user-frontend' ),
+            'description'      => __( 'Some description about this section', 'wp-user-frontend' ),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'description' => __( 'Some description about this section adshfdsh', 'wp-user-frontend' ),
'description' => __( 'Some description about this section', 'wp-user-frontend' ),

),
'cta' => sprintf(
'<a class="%1$s" href="%2$s" target="_blank">%3$s</a>',
'wpuf-px-[20px] wpuf-py-[10px] !wpuf-border !wpuf-border-solid !wpuf-border-gray-300 !wpuf-rounded-md hover:!wpuf-bg-gray-50 !wpuf-text-black',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify Tailwind CSS configuration.

The CTA button uses Tailwind CSS classes with 'wpuf-' prefix and '!' important modifiers. Ensure these classes are properly configured in your Tailwind setup.


🏁 Script executed:

#!/bin/bash
# Check if Tailwind CSS configuration exists and contains the custom prefix
fd -t f "tailwind.config" -x cat {} \; | grep -A 5 "prefix"

Length of output: 276


Tailwind CSS configuration verified; please correct the text for clarity.

  • The Tailwind config confirms the custom prefix "wpuf-" is properly set (see tailwind.config output).
  • Please update the CTA text from "Click here to get the these key" to "Click here to get these keys" and change the link text from "Go to Setting" to "Go to Settings" for grammatical accuracy.

:default_text="field.default"
:rich="field.rich"></text-editor>

<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify help text content sanitization.

The help text is rendered using v-html which could be vulnerable to XSS attacks if the content is not properly sanitized. Please ensure that field.help content is sanitized before rendering.


🏁 Script executed:

#!/bin/bash
# Search for help text sanitization implementation
rg -A 5 'field\.help'

# Search for any sanitization utilities
ast-grep --pattern $'function sanitize'

Length of output: 22919


Issues Found: Potential XSS risk via unsanitized help text content.

Our investigation did not reveal any sanitization functions (or equivalent logic) applied before rendering the help text via v-html. Field.help content is directly injected into the DOM, exposing the component to possible XSS vulnerabilities. Please ensure that all help text data is properly sanitized prior to being passed to the v-html directive.

Comment on lines 7 to 10
option_field: {
type: Object,
default: {}
default: () => ({ key: 'value' })
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the default value's impact on existing components.

While using a function for the default prop value is good practice, the generic { key: 'value' } default might not be appropriate for all field types and could potentially break existing components that expect an empty object.

Let's check how this prop is used across components:

Consider using a more specific default value based on the field type or maintaining backward compatibility with an empty object.


🏁 Script executed:

#!/bin/bash
# Search for components using the option_field prop
ast-grep --pattern 'option_field: {
  $$$
}'

# Search for direct references to option_field
rg 'option_field' -A 5

Length of output: 70473


Default Value May Cause Inconsistent Behavior in Components
Our investigation confirms that the option_field mixin is used widely, with many components expecting properties such as title, help_text, options, etc. Changing the default to a function that returns an object with a generic key (i.e. { key: 'value' }) is potentially problematic because none of the components rely on a “key” property and most check for other properties. This mismatch could lead to unexpected behavior when the prop is omitted. Consider reverting to an empty object or providing a more complete default that accommodates the expected structure.

Comment on lines 12 to 15
editing_form_field: {
type: Object,
default: {}
default: () => ({ key: 'value' })
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Ensure the default value doesn't break dependency checking.

The default value { key: 'value' } might cause issues in the met_dependencies computed property when checking for dependencies, as it expects specific field properties.

Let's verify the expected structure of editing_form_field:

Consider:

  1. Using a more comprehensive default value that includes all required properties
  2. Adding type checking or validation for required properties
  3. Maintaining backward compatibility with an empty object

🏁 Script executed:

#!/bin/bash
# Search for properties accessed on editing_form_field
rg 'editing_form_field\.' -A 5

# Search for dependencies usage
ast-grep --pattern 'dependencies: {
  $$$
}'

Length of output: 16554


Default value structure for editing_form_field appears insufficient.

The search results confirm many components access keys such as id, template, options, selected, min_column, and max_column from editing_form_field. Since the default value only returns { key: 'value' }, it doesn't provide the necessary structure, which can lead to runtime errors in dependency checking and other functionality.

• Update the default to include all required properties (e.g., id, template, options, etc.)
• Consider integrating type checking or additional validation for editing_form_field

@@ -32,13 +27,12 @@ Vue.component('form-column_field', {
sortableFields = $(self.$el).find('.wpuf-column-inner-fields .wpuf-column-fields-sortable-list'),
sortableTriggered = 1,
columnFieldArea = $('.wpuf-field-columns'),
columnFields = $(self.$el).find(".wpuf-column-field-inner-columns .wpuf-column-inner-fields");
columnFields = $(self.$el).find(".wpuf-field-columns .wpuf-column-inner-fields");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify DOM selector change impact.

The selector for column fields has been updated. Ensure this change doesn't break existing functionality.


🏁 Script executed:

#!/bin/bash
# Description: Check for other usages of the old selector
rg -A 2 "wpuf-column-field-inner-columns .wpuf-column-inner-fields" --type js

Length of output: 2221


Inconsistent DOM selector usage detected.
The grep output shows that while one instance uses the updated selector (".wpuf-field-columns .wpuf-column-inner-fields"), several other parts of the codebase in both admin/form-builder/assets/js/components/form-column_field/index.js and assets/js/wpuf-form-builder-components.js still reference the old selector (".wpuf-column-field-inner-columns .wpuf-column-inner-fields"). This inconsistency may break functionality if the DOM was updated to use the new class names.

• Update all references to use the new selector or confirm that legacy code paths are supported.
• Verify event handlers (mousemove, mouseup, etc.) tied to the old selector still function as expected with the updated DOM.

},

methods: {
is_template_available: function (field) {
var template = field.template;

if (this.field_settings[template]) {
if (this.is_pro_feature(template)) {
if (this.is_pro_preview(template)) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify method rename consistency.

The method call has been updated from is_pro_feature to is_pro_preview. Ensure all references are updated.


🏁 Script executed:

#!/bin/bash
# Description: Check for any remaining references to the old method name
rg "is_pro_feature" --type js

Length of output: 1223


Inconsistent method rename detected.
The RG output confirms that the old name ("is_pro_feature") is still present in several locations—such as in the method definitions (e.g., in admin/form-builder/assets/js/components/form-column_field/index.js) and other files—while at least one call site now uses "is_pro_preview". This discrepancy suggests that the renaming was only partly applied. Please update all references (both definitions and usages) to ensure that the new method name ("is_pro_preview") is used consistently across the codebase.

Comment on lines +54 to +55
$form_id = isset( $_GET['id'] ) ? intval( wp_unslash( $_GET['id'] ) ) : 0;

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Validate and sanitize GET parameter.

The form ID is retrieved from GET parameter without proper validation and sanitization.

-$form_id = isset( $_GET['id'] ) ? intval( wp_unslash( $_GET['id'] ) ) : 0;
+$form_id = isset( $_GET['id'] ) ? filter_var( wp_unslash( $_GET['id'] ), FILTER_VALIDATE_INT ) : 0;
+if ( false === $form_id ) {
+    $form_id = 0;
+}

Comment on lines +391 to +393
$url = 'https://raw.githubusercontent.com/weDevsOfficial/wpuf-util/master/pro-field-assets.json';
$response = wp_remote_get( $url, [ 'timeout' => 15 ] );
$info = wp_remote_retrieve_body( $response );
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Improve error handling for remote JSON fetching.

The remote JSON fetching lacks proper error handling and logging.

+$url = apply_filters( 'wpuf_pro_field_assets_url', 'https://raw.githubusercontent.com/weDevsOfficial/wpuf-util/master/pro-field-assets.json' );
 $response = wp_remote_get( $url, [ 'timeout' => 15 ] );
+
+if ( is_wp_error( $response ) ) {
+    error_log( sprintf( 'WPUF Pro Field Assets Error: %s', $response->get_error_message() ) );
+    return [];
+}
+
 $info = wp_remote_retrieve_body( $response );
+
+if ( empty( $info ) ) {
+    error_log( 'WPUF Pro Field Assets Error: Empty response body' );
+    return [];
+}
+
+$decoded = json_decode( $info, true );
+if ( json_last_error() !== JSON_ERROR_NONE ) {
+    error_log( sprintf( 'WPUF Pro Field Assets Error: %s', json_last_error_message() ) );
+    return [];
+}

Comment on lines 252 to 253
$billing_amount = apply_filters( 'wpuf_payment_amount', $cost );
$tax_amount = $billing_amount - $cost;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🛠️ Refactor suggestion

🧩 Analysis chain

Review tax calculation order

The current implementation calculates tax after applying filters to the billing amount, which could lead to incorrect tax calculations if the filters modify the amount. Consider calculating tax before applying filters to ensure accurate tax computation.

Apply this change to fix the tax calculation order:

-            $billing_amount = apply_filters( 'wpuf_payment_amount', $cost );
-            $tax_amount     = $billing_amount - $cost;
+            $tax_amount     = 0; // Calculate tax based on original cost
+            $billing_amount = apply_filters( 'wpuf_payment_amount', $cost + $tax_amount );

🏁 Script executed:

#!/bin/bash
# Extract lines 250 to 260 from includes/Admin/Admin_Subscription.php to verify the current tax calculation logic
sed -n '250,260p' includes/Admin/Admin_Subscription.php

Length of output: 642


Action: Reevaluate Tax Calculation Order in Admin Subscription

The current implementation applies filters to the original cost and then derives the tax amount by subtracting the unfiltered cost. This approach relies on the filter exclusively adding tax, which may not always be the case. To avoid potential inaccuracies, it’s better to calculate the tax based solely on the original cost before applying any filters that modify the amount.

  • Calculate tax using the unmodified cost.
  • Apply filters after the tax computation to ensure clarity and consistency.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
assets/js-templates/form-components.php (1)

124-124: ⚠️ Potential issue

Potential XSS vulnerability with v-html directive.

The code uses v-html to render dynamic content without sanitization, which could lead to XSS attacks.

Consider sanitizing the content before rendering:

-<div class="wpuf-absolute wpuf-w-full wpuf-h-full wpuf-z-10"></div>
+<div class="wpuf-absolute wpuf-w-full wpuf-h-full wpuf-z-10" v-text="sanitizeHTML(content)"></div>

Also applies to: 815-815

admin/form-builder/assets/js/components/form-radio_field/template.php (1)

31-31: ⚠️ Potential issue

Sanitize HTML content before rendering.

Using v-html with unsanitized content can expose the application to XSS attacks.

admin/form-builder/assets/js/components/field-select/template.php (1)

7-15: ⚠️ Potential issue

Enhance accessibility of the custom dropdown.

The custom dropdown implementation needs accessibility improvements:

  1. Missing ARIA attributes for dropdown state and role
  2. No keyboard navigation support
  3. Missing focus indicators
admin/form-builder/assets/js/form-builder.js (1)

622-624: 🛠️ Refactor suggestion

Use Vuex mutation for panel sections update

Direct state mutation should be avoided. Use a Vuex mutation instead.

-this.$store.state.panel_sections = wpuf_form_builder.panel_sections;
+this.$store.commit('set_panel_sections', wpuf_form_builder.panel_sections);
🧹 Nitpick comments (9)
assets/js-templates/form-components.php (2)

1022-1028: Enhance accessibility with ARIA attributes.

Interactive elements like buttons and inputs should have proper ARIA attributes for better screen reader support.

Consider adding ARIA attributes:

 <input
     type="text"
     name="search"
     id="search"
     v-model="searched_fields"
+    aria-label="Search fields"
+    role="searchbox"
     class="!wpuf-border-none !wpuf-rounded-lg wpuf-block wpuf-min-w-0 wpuf-grow wpuf-px-4 wpuf-py-1.5 wpuf-text-base wpuf-text-gray-900 placeholder:wpuf-text-gray-400 sm:wpuf-text-sm/6 !wpuf-shadow-none !wpuf-ring-transparent"
     placeholder="Search Field">

Also applies to: 1152-1154


771-894: Consider performance optimizations for complex layouts.

The column field template involves complex DOM manipulations and nested v-for directives which could impact performance with large datasets.

Consider these optimizations:

  1. Use v-show instead of v-if for frequently toggled elements
  2. Add key attributes to all v-for elements
  3. Consider virtualizing long lists
  4. Use computed properties for filtered data instead of filtering in template
admin/form-builder/assets/js/mixins/form-field.js (1)

9-9: Consider a more descriptive default field structure.

The current default { key: 'value' } is generic. Consider using a more meaningful default structure that aligns with the field's expected properties.

-            default: () => ({ key: 'value' })
+            default: () => ({
+                name: '',
+                type: '',
+                options: {},
+                selected: null
+            })
assets/js/wpuf-form-builder-mixins.js (1)

109-139: Consider extracting common class names

The builder_class_names method effectively handles different field types, but there's some duplication in the class names. Consider extracting common classes into a shared constant or configuration object.

+ // At the top of the file
+ const COMMON_FIELD_CLASSES = {
+   base: 'wpuf-block wpuf-min-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 wpuf-border !wpuf-border-gray-300',
+   radio: 'wpuf-mx-3 !wpuf-my-0 wpuf-block wpuf-text-base wpuf-font-medium wpuf-text-gray-900',
+   checkbox: 'wpuf-h-4 wpuf-w-4 wpuf-rounded wpuf-border-gray-300 !wpuf-mt-0.5'
+ };

 builder_class_names: function(type_class) {
     var commonClasses = '';
     
     switch (type_class) {
         case 'upload_btn':
             commonClasses = 'file-selector wpuf-rounded-md wpuf-btn-secondary';
             break;
             
         case 'radio':
-            commonClasses = 'wpuf-mx-3 !wpuf-my-0 wpuf-block wpuf-text-base wpuf-font-medium wpuf-text-gray-900 checked:focus:!wpuf-bg-primary checked:hover:!wpuf-bg-primary checked:before:!wpuf-bg-white checked:!wpuf-bg-primary';
+            commonClasses = `${COMMON_FIELD_CLASSES.radio} checked:focus:!wpuf-bg-primary checked:hover:!wpuf-bg-primary checked:before:!wpuf-bg-white checked:!wpuf-bg-primary`;
             break;
             
         // ... rest of the cases
     }
src/css/admin/form-builder.css (2)

5-29: Components Layer – Custom Classes and @apply Usage

The custom component classes (e.g., .wpuf-btn-primary, .wpuf-btn-secondary, .wpuf-tooltip-top) properly utilize the Tailwind @apply directive. One minor note:

  • In the .wpuf-input-checkbox (lines 18-20) and similar blocks, consider appending a semicolon at the end of the @apply declarations for consistency and clarity.

58-63: Potential Conflict in .wpuf-pattern-1 Styles

In the .wpuf-pattern-1 block, a background-color is set on line 60 and then a shorthand background property is defined on line 62. Since the shorthand property overrides the earlier background-color, ensure this is intentional. If you intended a fallback, a comment would help clarify the reasoning.

🧰 Tools
🪛 Biome (1.9.4)

[error] 62-62: Unexpected shorthand property background after background-color

(lint/suspicious/noShorthandPropertyOverrides)

admin/form-builder/assets/js/form-builder.js (2)

93-109: Consider using async/await for better readability

The open_field_settings mutation uses a setTimeout to handle field ID updates. Consider using async/await for better readability and control flow.

-setTimeout( function () {
-    state.editing_field_id = field[0].id;
-}, 400 );
+await new Promise(resolve => setTimeout(resolve, 400));
+state.editing_field_id = field[0].id;

1021-1025: Remove commented code

The commented code for resizeBuilderContainer should be either removed or uncommented if needed.

-// resizeBuilderContainer();
-//
-// $("#collapse-menu").click(function () {
-//     resizeBuilderContainer();
-// });
assets/js/wpuf-form-builder-components.js (1)

2126-2130: Consider using Vue-specific tooltip library

Using jQuery tooltip with Vue components can lead to memory leaks. Consider using a Vue-specific tooltip library for better integration.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 69c6621 and 584c78e.

📒 Files selected for processing (11)
  • admin/form-builder/assets/js/components/field-radio/index.js (1 hunks)
  • admin/form-builder/assets/js/components/field-radio/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-select/template.php (1 hunks)
  • admin/form-builder/assets/js/components/form-radio_field/template.php (1 hunks)
  • admin/form-builder/assets/js/form-builder.js (17 hunks)
  • admin/form-builder/assets/js/mixins/form-field.js (3 hunks)
  • assets/js-templates/form-components.php (19 hunks)
  • assets/js/wpuf-form-builder-components.js (16 hunks)
  • assets/js/wpuf-form-builder-mixins.js (7 hunks)
  • assets/js/wpuf-form-builder.js (17 hunks)
  • src/css/admin/form-builder.css (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • admin/form-builder/assets/js/components/field-radio/template.php
🧰 Additional context used
🪛 Biome (1.9.4)
src/css/admin/form-builder.css

[error] 159-159: expected } but instead the file ends

the file ends here

(parse)


[error] 62-62: Unexpected shorthand property background after background-color

(lint/suspicious/noShorthandPropertyOverrides)

assets/js/wpuf-form-builder.js

[error] 617-617: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

admin/form-builder/assets/js/form-builder.js

[error] 617-617: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

assets/js/wpuf-form-builder-components.js

[error] 332-332: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 332-332: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 355-355: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 363-363: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 301-301: This aliasing of this is unnecessary.

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

(lint/complexity/noUselessThisAlias)


[error] 1684-1684: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (24)
assets/js-templates/form-components.php (2)

85-91: LGTM! Improved empty state handling.

The new empty state provides better user guidance with:

  • Clear visual hierarchy using an illustration
  • Descriptive header text
  • Helpful subtext

1018-1052: LGTM! Enhanced search functionality.

The new search implementation provides:

  • Clear visual feedback
  • Accessible input field
  • Clear button for better UX
admin/form-builder/assets/js/components/field-radio/index.js (1)

5-6: LGTM! Good enhancement of the radio field component.

The addition of wpuf_mixins.form_field_mixin alongside the existing option_field_mixin enhances the component's styling capabilities through the builder_class_names method.

admin/form-builder/assets/js/components/form-radio_field/template.php (1)

8-13: ⚠️ Potential issue

Fix radio button input and label attributes.

The radio button implementation has several issues:

  1. Missing crucial input attributes (name, value, id)
  2. Incorrect attribute placement between input and label elements

Apply this diff:

             <input
                 type="radio"
+                :name="field.name"
+                :value="val"
+                :id="field.name + '_' + val"
+                v-model="field.selected"
                 :class="builder_class_names('radio')">
             <label
-                :value="val"
-                :checked="is_selected(val)"
+                :for="field.name + '_' + val"
                 >{{ label }}</label>

Likely invalid or redundant comment.

admin/form-builder/assets/js/mixins/form-field.js (1)

36-66: LGTM! Well-structured class name builder.

The builder_class_names method provides a consistent way to apply Tailwind CSS classes based on field types. The switch statement makes it easy to maintain and extend styles for different field types.

assets/js/wpuf-form-builder-mixins.js (2)

23-34: LGTM! Enhanced error notification modal

The changes improve the visual presentation of the error notification modal with proper styling and structure.


60-64: LGTM! Well-structured pro feature check

The new is_pro_preview method provides a clean and reusable way to check if a template is a pro feature when the pro version is inactive.

src/css/admin/form-builder.css (12)

1-3: Tailwind CSS Directives Imported Properly

The base, components, and utilities layers are imported as expected. Ensure that your Tailwind configuration is set up to recognize the custom “wpuf-” prefixed classes.


31-47: Utilities Layer Defined Correctly

The transition and scale utility classes are clear and correctly defined. Their simplicity should help maintain consistency across component animations.


49-56: Dropdown Transition Styles

The styles for .wpuf-dropdown-item and its hover state under .wpuf-dropdown-container are clear and succinctly leverage the utility classes. Nice work.


65-68: Selectize Data-Value Styling

The rules applied to the [data-value] attribute under the .selectize-control.multi .selectize-input selector are clear. The use of !important appears deliberate to enforce these styles.


70-93: Form Fields Width Rules – Verify Specificity and Duplication

There are several rules for setting widths on form fields:
• Lines 70–72 and 88–90 both set widths for field-size-small, and similarly for field-size-medium (lines 74–76 and 85–87), with the latter using !important.
• A generic rule at lines 91–93 sets a 70% width for all li .wpuf-fields under a body selector.
Review these rules to ensure there’s no unintended conflict or duplication. Consolidating these could improve maintainability.


94-100: Sidebar Menu Icon Styling

The SVG icon styles for the sidebar menu, including hover and active state rules, are well defined and should enhance visual consistency.


101-110: Selectize Control Appearance

The styling for .selectize-control and its variants is appropriately managed, with borders and background colors clearly set. The use of !important in these contexts seems intentional to override any default styles.


111-128: Icon Container Base Styles

The .wpuf-icon-container and its children (img) are styled correctly for positioning and responsive behavior. The fallback background and overflow handling will ensure images display as expected.


131-134: Icon Container Loaded State

The rules that adjust opacity for loaded images and iframes in the icon container are concise and effective.


135-149: Shimmer Animation for Loading States

The .wpuf-shimmer class uses a linear-gradient and animation to create a shimmer effect, and the accompanying transition properties are well specified for smooth animation. The structure is clear.


150-153: Keyframes Definition for Shimmer Animation

The @Keyframes wpuf-shimmer block is correctly defined, transitioning from off-screen left to off-screen right. This aligns with the intended shimmering effect.


157-159: Final Rule and File Termination

The #wpcontent rule is simple and correctly closed. However, a static analysis hint noted a missing closing bracket or newline at the end of the file. Ensure the file ends with a newline character to comply with standard formatting practices.
[refactor_suggestion_good_to_have, verify]

🧰 Tools
🪛 Biome (1.9.4)

[error] 159-159: expected } but instead the file ends

the file ends here

(parse)

admin/form-builder/assets/js/form-builder.js (3)

44-46: LGTM: State properties for form versioning

The new state properties is_older_form and is_post_form provide clear versioning control, with current_panel being conditionally set based on these flags.


395-403: LGTM: Panel section mutations

The new mutations set_panel_sections and set_default_panel_sections provide a clean way to manage panel sections state.


617-617: Simplify boolean toggle

The ternary operator for boolean toggle can be simplified using the logical NOT operator.

-this.is_form_switcher = (this.is_form_switcher) ? false : true;
+this.is_form_switcher = !this.is_form_switcher;
🧰 Tools
🪛 Biome (1.9.4)

[error] 617-617: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

assets/js/wpuf-form-builder.js (2)

188-370: LGTM: New builder stage component

The new builder-stage-v4-1 component properly extends the existing functionality with improved sortable handling and field management.


1553-1769: LGTM: Enhanced form fields panel

The new form-fields-v4-1 component adds search functionality and improves field management with proper cleanup of draggable bindings.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
assets/js-templates/form-components.php (2)

106-106: Consider extracting common Tailwind classes into reusable utilities.

Multiple components share similar class combinations for styling. Consider extracting these into reusable utilities to improve maintainability and reduce duplication. For example:

- class="wpuf-group wpuf-rounded-lg hover:!wpuf-bg-green-50 wpuf-transition wpuf-duration-150 wpuf-ease-out !wpuf-m-0 !wpuf-p-0"
+ class="wpuf-field-container"

Add the utility class to your Tailwind configuration:

/* tailwind.config.js */
module.exports = {
  theme: {
    extend: {
      utilities: {
        '.wpuf-field-container': {
          '@apply wpuf-group wpuf-rounded-lg hover:!wpuf-bg-green-50 wpuf-transition wpuf-duration-150 wpuf-ease-out !wpuf-m-0 !wpuf-p-0',
        },
      },
    },
  },
}

Also applies to: 145-145, 836-836


1159-1161: Consider extracting SVG icons into a separate component.

SVG icons are repeated across multiple templates. Consider creating a reusable icon component to improve maintainability and reduce duplication:

- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="wpuf-size-5">
-   <path d="M8.75 3.75a.75.75 0 0 0-1.5 0v3.5h-3.5a.75.75 0 0 0 0 1.5h3.5v3.5a.75.75 0 0 0 1.5 0v-3.5h3.5a.75.75 0 0 0 0-1.5h-3.5v-3.5Z" />
- </svg>
+ <wpuf-icon name="plus" class="wpuf-size-5" />

Also applies to: 1165-1167, 1207-1209

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 584c78e and 854c8ab.

📒 Files selected for processing (6)
  • admin/form-builder/assets/js/components/builder-stage-v4-1/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-range/template.php (1 hunks)
  • admin/form-builder/assets/js/components/field-visibility/template.php (3 hunks)
  • admin/form-builder/assets/less/form-builder.less (4 hunks)
  • assets/css/wpuf-form-builder.css (4 hunks)
  • assets/js-templates/form-components.php (20 hunks)
✅ Files skipped from review due to trivial changes (1)
  • admin/form-builder/assets/js/components/field-range/template.php
🚧 Files skipped from review as they are similar to previous changes (4)
  • admin/form-builder/assets/js/components/field-visibility/template.php
  • admin/form-builder/assets/js/components/builder-stage-v4-1/template.php
  • admin/form-builder/assets/less/form-builder.less
  • assets/css/wpuf-form-builder.css
🔇 Additional comments (4)
assets/js-templates/form-components.php (4)

275-275: Validate or sanitize HTML before rendering with "v-html".

Lines within this block use v-html (e.g., for showing help text). If the field data is not sanitized server-side, this could be a potential XSS vector. Ensure that only trusted content is rendered, or apply sanitization.

Also applies to: 753-753, 909-909, 965-965, 1174-1174, 1243-1243, 1258-1258, 1272-1272, 1307-1307, 1392-1392, 1405-1405, 1425-1425, 1438-1438


85-91: LGTM! Enhanced empty state UI.

The new empty state UI with image and descriptive text provides better user guidance.


1021-1056: LGTM! Improved field search functionality.

The new search functionality with clear button and visual feedback enhances the user experience.


1134-1139: 🛠️ Refactor suggestion

Make strings translatable.

Hardcoded strings should be wrapped with translation functions for internationalization:

- <h2 class="wpuf-text-slate-600 wpuf-text-xl wpuf-font-bold wpuf-mb-4">
-   Got an idea for a new field?
- </h2>
- <p class="wpuf-text-slate-600 wpuf-mb-6">
-   We'd love to hear it!
- </p>
+ <h2 class="wpuf-text-slate-600 wpuf-text-xl wpuf-font-bold wpuf-mb-4">
+   <?php esc_html_e( 'Got an idea for a new field?', 'wp-user-frontend' ); ?>
+ </h2>
+ <p class="wpuf-text-slate-600 wpuf-mb-6">
+   <?php esc_html_e( 'We\'d love to hear it!', 'wp-user-frontend' ); ?>
+ </p>

Likely an incorrect or invalid review comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant