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: field options sidebar #1505

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

Conversation

sapayth
Copy link
Member

@sapayth sapayth commented Dec 20, 2024

fixes #640, fixes 657

Add Fields, Field Options part for form builder UI enhancement. Image below for better understanding:

image

Summary by CodeRabbit

  • New Features

    • Introduced a new Vue component for form fields management with enhanced search capabilities.
    • Added support for Tailwind CSS file handling in the build process.
    • New modal interface for selecting post form templates.
    • New field types: Time and Phone added to the form builder.
  • Improvements

    • Enhanced rendering logic for various form fields, improving styling and accessibility.
    • Improved tooltip functionality for help text components.
    • Dynamic class bindings added to various form elements for better styling.
  • Bug Fixes

    • Corrected logic for rendering conditions in several components.
    • Fixed issues with property defaults in field mixins.
  • Documentation

    • Updated comments and documentation for various methods to clarify functionality and usage.
  • Chores

    • Cleaned up and refactored CSS styles for improved maintainability and responsiveness.

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 Dec 20, 2024

Walkthrough

The pull request introduces a comprehensive update to the WP User Frontend (WPUF) plugin, focusing on enhancing the form builder interface, styling, and functionality. The changes span multiple files across JavaScript, PHP, and CSS, introducing new components, updating existing ones, and refining the user experience. Key modifications include updating form templates, improving form field interactions, and modernizing the admin and frontend interfaces.

Changes

File Change Summary
Lib/Appsero/Client.php Updated get_plugin_data() function call with additional parameters
admin/form-builder/assets/js/components/* Numerous Vue.js component updates with new mixins, styling, and interaction improvements
assets/js/wpuf-form-builder-components.js Added new components and updated existing ones with mixins
includes/Admin/Forms/Admin_Form_Builder.php Added new action hook and modified form builder view inclusion logic
includes/Assets.php Added new style entry for admin form builder

Assessment against linked issues

Objective Addressed Explanation
Fix page order being reset to 0 when editing from frontend [#640] Unable to definitively confirm from the provided changes. The pull request does not show direct modifications to page order handling.

Poem

🐰 A Rabbit's Ode to Form-Building Delight

Mixins dancing, styles so bright,
Vue components take their flight,
From PNG to SVG's gleam,
WPUF's builder, a coder's dream!

🎨✨

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


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: 24

🔭 Outside diff range comments (3)
assets/js/wpuf-form-builder.js (1)

Line range hint 93-108: Optimize Field Lookup in open_field_settings

Use an early return if the field is not found (field.length is 0) to skip extra checks. This helps avoid referencing field[0] when the array is empty.

 if (!field.length) {
+    return;
 }
 if ('field-options' === state.current_panel && field[0].id === ...
admin/form-builder/assets/js/form-builder.js (1)

Line range hint 93-108: Defensive Programming: Check Existence of Field[0]

When retrieving field[0], consider verifying field.length first, to avoid referencing an index out of bounds.

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

Line range hint 8-15: Refactor tooltip configuration to use placement prop

The placement prop is defined with validation but not used in the tooltip initialization. Consider these improvements:

 props: {
     text: {
         type: String,
         default: ''
     },
     placement: {
         type: String,
         default: 'top',
-        validator: function (placement) {
-            return ['top', 'right', 'bottom', 'left'].indexOf(placement) >= 0;
-        }
+        validator: function (placement) {
+            return ['auto top', 'auto right', 'auto bottom', 'auto left'].indexOf(placement) >= 0;
+        }
     }
 },
 mounted: function () {
     $( this.$el ).tooltip({
         title: this.text,
-        placement: 'auto top'
+        placement: this.placement
     });
 }

Also consider adding a watcher for prop changes:

watch: {
    text(newVal) {
        $(this.$el).tooltip('dispose').tooltip({
            title: newVal,
            placement: this.placement
        });
    },
    placement(newVal) {
        $(this.$el).tooltip('dispose').tooltip({
            title: this.text,
            placement: newVal
        });
    }
}

Also applies to: 20-23

🧹 Nitpick comments (53)
admin/form-builder/assets/js/components/form-image_upload/template.php (1)

8-10: Enhance accessibility for the upload button.

The SVG icon and layout look good, but we should improve accessibility.

Add these accessibility attributes:

-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="wpuf-size-5">
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="wpuf-size-5" 
+    role="img" aria-hidden="true">
admin/form-builder/assets/js/components/form-textarea_field/template.php (1)

11-14: Consider improving the rich text editor conditional logic

The current implementation has a few potential improvements:

  1. The condition 'no' !== field.rich could be more explicit
  2. The prop naming is inconsistent (default_text vs default)

Consider this refactoring:

-    <text-editor
-        v-if="'no' !== field.rich"
-        :default_text="field.default"
-        :rich="field.rich"></text-editor>
+    <text-editor
+        v-if="field.rich === 'yes'"
+        :default="field.default"
+        :rich="field.rich"></text-editor>
admin/form-builder/assets/js/components/field-option-data/template.php (3)

2-5: Enhance accessibility by ensuring clear labeling
You're using a label (line 3) together with Vue data bindings (line 4). Consider adding a “for” attribute or an ARIA attribute that references the applicable control for better accessibility. In addition, double-check that screen readers can properly associate this label with any related checkbox or text field.


72-78: Consider client-side validations for numeric or enumerated values
“Value” fields in lines 74-77 allow any text input. If you need strictly numeric or enumerated data, add client-side checks or validations.


80-110: Streamline icon usage
You’re using inline SVG icons, which is fine. If they’re used frequently, consider centralizing them in a reusable SVG component or referencing a sprite for consistency and lower DOM overhead.

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

86-88: Consider removing the “self = this” alias
On line 115 (within the delete_field method), the code assigns “var self = this;” but uses an arrow callback. Arrow functions already capture “this” from the parent scope. Removing this alias can make the code more concise.

Here’s a quick snippet:

-delete_field: function(index) {
-    var self = this;
-    (Swal.fire({...})).then((result) => {
-        if (result.isConfirmed) {
-            self.$store.commit('delete_form_field_element', index);
-        }
-    });
+delete_field: function(index) {
+    Swal.fire({...}).then((result) => {
+        if (result.isConfirmed) {
+            this.$store.commit('delete_form_field_element', index);
+        }
+    });
 },

146-146: Simplify the boolean expression & use optional chaining
Line 146: “return (this.field_settings[template] && this.field_settings[template].pro_feature) ? true : false;”

Use optional chaining and a logical NOT operator or double NOT to remove unnecessary ternary booleans.

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

[error] 146-146: 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] 146-146: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


169-169: Use optional chaining
Line 169: A similar optional chaining enhancement would reduce complexity.

-is_full_width: function (template) {
-    if (this.field_settings[template] && this.field_settings[template].is_full_width) {
-        return true;
-    }
-    return false;
+is_full_width: function (template) {
+    return !!this.field_settings?.[template]?.is_full_width;
 }
🧰 Tools
🪛 Biome (1.9.4)

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


177-177: Remove redundant ternary
Line 177: “return (field.recaptcha_type && 'invisible_recaptcha' === field.recaptcha_type) ? true : false;”

Consider simplifying to a direct comparison for clarity.

-is_invisible: function (field) {
-    return ( field.recaptcha_type && 'invisible_recaptcha' === field.recaptcha_type ) ? true : false;
+is_invisible: function (field) {
+    return field.recaptcha_type === 'invisible_recaptcha';
 }
🧰 Tools
🪛 Biome (1.9.4)

[error] 177-177: 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/components/form-column_field/template.php (1)

57-105: UI clarity
The control buttons and icons are well grouped. The usage of “group-hover” transitions is a nice modern pattern. Keep an eye on color contrast for accessibility.

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

55-114: Button states
On lines 58–77, you handle disabled vs. enabled states with separate templates. This is functional, but consider toggling classes on the same elements instead of duplicating them in separate blocks. This can reduce code duplication.


121-192: Hidden fields management
It’s excellent that hidden fields get their own section. This helps keep the UI less cluttered. Confirm that the user is clearly informed about which fields are hidden from the site visitors once the form is generated.

admin/form-builder/views/form-builder-v4.1.php (2)

13-18: Improve Accessibility with Placeholder or aria-label

Consider adding accessibility attributes (e.g., placeholder, aria-label) for the title input when not editing to make it more screen-reader friendly.


169-173: Enhance UX with Quick Field Option Access

The “Field Options” tab is placed alongside “Add Fields.” For complex forms, consider giving a quick highlight or direct link in the “Add Fields” panel to jump to “Field Options” for faster configuration.

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

45-46: Avoid Redundant Condition in is_post_form

This line duplicates the condition for “is_older_form && post.post_type === 'wpuf_forms'.” Consider simplifying this logic for readability.


602-603: Consider Avoiding Magic Panel Strings

When saving, the panel is forced to either 'form-fields' or 'form-fields-v4-1.' Consider an enum or constant reference in Vuex to avoid string-based references scattered throughout the code.

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

423-428: Prevent Data Loss on Page Unload

“isDirty” is set to true on form changes, prompting a confirm exit. That’s good. Consider implementing a manual “Save or Discard” prompt for additional user clarity.

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

303-303: Avoid Unnecessary Alias for self

Static analysis indicates that aliasing “this” to “self” in an arrow function is unnecessary. Removing the extra variable can simplify the code.

🧰 Tools
🪛 Biome (1.9.4)

[error] 303-303: 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)


334-334: Remove Ternary with Boolean Literals

Static analysis flags lines with boolean literal usage in a ternary. Instead of “return x ? true : false;” just “return !!x.” This is more succinct and clarifies intent.

- return something ? true : false;
+ return !!something;

Also applies to: 365-365

🧰 Tools
🪛 Biome (1.9.4)

[error] 334-334: 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] 334-334: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


1612-1612: Optional Chaining Recommendation

Where feasible, consider optional chaining to read nested properties safely. For instance, “validator?.msg” can help avoid crashes if “validator” is undefined.

🧰 Tools
🪛 Biome (1.9.4)

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


1635-1635: Eliminate Redundant Aliasing of this with self

Static analysis warns about reassigning this context to “self.” Using arrow functions provides lexical scoping for “this,” so “self” is typically unneeded.

🧰 Tools
🪛 Biome (1.9.4)

[error] 1635-1635: 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)

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

85-94: Use consistent wrapping & nesting for improved maintainability.
The new template starts with a different structure than the existing one, but both seem to serve similar purposes (rendering the form stage). Consider aligning the wrapper classes and structure to avoid confusion when maintaining multiple versions of the same template.


140-185: Localize text labels for better i18n coverage.
Strings like “Copy,” “Edit,” and “Remove” are embedded within control buttons. For multilingual support, consider wrapping these strings in translation functions or placeholders so that they can be localized.


202-205: Clarify hidden submit block usage.
It looks like you insert a hidden list item for submit behavior. Add a short comment or rename the class to clarify the rationale (e.g., “Submit block is hidden on the builder stage but shown during actual rendering”).


302-316: Keep multi-select styles consistent.
The new classes (e.g., “wpuf-border-primary”) should remain consistent across all select-based fields. Confirm that similarly styled components (radio, dropdown) also use matching Tailwind or utility classes for visual coherence.


Line range hint 448-484: Segment advanced settings for uniform code structure.
Basic and advanced settings are toggled with similar logic. These blocks can be further standardized (like using a shared “toggle-section” mixin or partial). That would enhance code reusability and reduce accidental divergence.

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

7-8: Consider consolidating class handling approach.

The component uses both dynamic (:class="class_names('textfield')") and static Tailwind classes. This could lead to:

  • Potential style conflicts
  • Maintenance challenges
  • Specificity issues (note the ! important flag)

Consider moving all styling to the dynamic class binding for better maintainability.

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

12-15: Consider using v-bind shorthand for multiple attributes

The option elements could be more concisely written using v-bind object syntax.

-        <option
-            class="checked:wpuf-bg-primary"
-            v-for="(option, key) in option_field.options"
-            :value="key">{{ option }}</option>
+        <option
+            v-for="(option, key) in option_field.options"
+            v-bind="{
+                class: 'checked:wpuf-bg-primary',
+                value: key
+            }"
+        >{{ option }}</option>
admin/form-builder/assets/js/components/form-dropdown_field/template.php (1)

4-4: Consider extracting common class patterns

The select element has multiple utility classes that might be reused across other form elements. Consider extracting these into a shared class or component-level style definition.

- class="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"
+ :class="[
+   'wpuf-form-control', // New shared class
+   'wpuf-select-field'  // Field-specific class
+ ]"
admin/form-builder/assets/js/components/field-text-meta/template.php (1)

12-12: Review CSS specificity overrides

The use of ! (important) flags in CSS classes (!wpuf-shadow-sm, !wpuf-border, !wpuf-border-gray-300) suggests potential specificity issues. Consider refactoring the CSS architecture to avoid specificity battles.

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

15-15: Refactor duplicate class bindings

The builder_class_names('text') is duplicated for both input variations. Consider extracting common attributes to reduce duplication.

+    <template v-if="option_field.variation && 'number' === option_field.variation">
         <input
-            v-if="option_field.variation && 'number' === option_field.variation"
             type="number"
             v-model="value"
             @focusout="on_focusout"
             @keyup="on_keyup"
             :class="builder_class_names('text')">
+    </template>
+    <template v-else>
         <input
-            v-if="!option_field.variation"
             type="text"
             v-model="value"
             @focusout="on_focusout"
             @keyup="on_keyup"
             :class="builder_class_names('text')">
+    </template>

Also applies to: 23-23


9-15: Consider combining event handlers

The input elements share identical event handlers. Consider creating a computed property or method that returns the common input attributes to reduce code duplication.

Example approach:

computed: {
  inputProps() {
    return {
      'v-model': 'value',
      '@focusout': 'on_focusout',
      '@keyup': 'on_keyup',
      'class': this.builder_class_names('text')
    }
  }
}

Then in template:

-            v-model="value"
-            @focusout="on_focusout"
-            @keyup="on_keyup"
-            :class="builder_class_names('text')"
+            v-bind="inputProps"

Also applies to: 17-23

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

9-18: Consider adding aria-label for better accessibility

The dashed section break implementation looks good, but could benefit from improved accessibility for screen readers.

Consider adding an aria-label to the outer div:

     <div
         v-else-if="field.divider === 'dashed'"
-        class="wpuf-section-wrap">
+        class="wpuf-section-wrap"
+        :aria-label="field.label + ' section'">
admin/form-builder/assets/js/components/form-featured_image/template.php (1)

10-12: Consider adding aria-label for better accessibility

While the SVG icon enhances visual appeal, it should be accompanied by appropriate accessibility attributes.

-    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="wpuf-size-5">
+    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="wpuf-size-5" aria-hidden="true" role="img">
admin/form-builder/assets/js/components/form-checkbox_field/template.php (1)

36-36: Add ID to help text for ARIA association

The help text should be properly associated with the form controls using ARIA attributes.

-<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
+<p v-if="field.help" :id="`${field.name}-help`" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
admin/form-builder/assets/js/components/form-radio_field/template.php (2)

2-32: Reduce code duplication in radio button layouts

The inline and non-inline layouts share similar code structure. Consider extracting common parts into a reusable template or component.

+ <!-- Create a new component RadioOption.vue -->
+ <template>
+   <div class="wpuf-flex wpuf-items-center">
+     <input
+       type="radio"
+       :class="getInputClasses()"
+       class="wpuf-border-gray-300 wpuf-text-indigo-600">
+     <label
+       :value="value"
+       :checked="checked"
+       :class="[
+         'wpuf-ml-3 wpuf-block wpuf-text-sm wpuf-font-medium wpuf-leading-6 wpuf-text-gray-900',
+         ...labelClasses
+       ]">
+       {{ label }}
+     </label>
+   </div>
+ </template>

10-10: Avoid using !important in CSS classes

The use of !wpuf-m-0 suggests specificity issues in the CSS. Consider:

  1. Restructuring CSS to avoid specificity conflicts
  2. Using more specific selectors if necessary

Also applies to: 25-25

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

28-29: Standardize spacing classes

The margin class wpuf-ml-2 is conditionally applied using a ternary. Consider using a CSS Grid or Flexbox gap for consistent spacing.

- :class="index !== 0 ? 'wpuf-ml-2' : ''"
+ class="wpuf-gap-x-2"  <!-- Add to parent div -->

13-18: Enhance radio button accessibility

Add aria-label or aria-labelledby attributes to improve screen reader support.

 <input
   type="radio"
   :value="key"
   v-model="value"
+  :aria-label="option"
   class="checked:!wpuf-bg-primary checked:before:!wpuf-bg-transparent">

Also applies to: 30-35

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

49-54: LGTM! Consider extracting common CSS classes.

The computed property implementation is clean and follows Vue.js best practices. However, since these classes might be reused across components, consider extracting them into a shared constants file or utility function.

+ // constants/styles.js
+ export const BUTTON_CLASSES = {
+   ACTION: 'wpuf-p-2 hover:wpuf-cursor-pointer hover:wpuf-text-white'
+ };

  computed: {
    action_button_classes: function() {
-     return 'wpuf-p-2 hover:wpuf-cursor-pointer hover:wpuf-text-white';
+     return BUTTON_CLASSES.ACTION;
    }
  },
admin/form-builder/assets/js/components/field-options/template.php (2)

9-15: LGTM! Consider enhancing accessibility.

The dynamic styling and layout implementation looks good. However, consider adding ARIA attributes for better accessibility.

  <h3
    :class="show_basic_settings ? 'wpuf-text-green-600' : 'wpuf-text-gray-500'"
    class="wpuf-flex wpuf-mt-0 wpuf-mb-6 wpuf-justify-between hover:wpuf-cursor-pointer wpuf-text-sm"
-   @click="show_basic_settings = !show_basic_settings">
+   @click="show_basic_settings = !show_basic_settings"
+   role="button"
+   :aria-expanded="show_basic_settings"
+   :aria-controls="'basic-settings-content'">

32-37: Apply the same accessibility improvements here.

For consistency, apply the same ARIA attributes to the advanced settings section.

  <h3
    :class="show_advanced_settings ? 'wpuf-text-green-600' : 'wpuf-text-gray-500'"
    class="wpuf-flex wpuf-mt-0 wpuf-mb-6 wpuf-justify-between hover:wpuf-cursor-pointer wpuf-text-sm"
-   @click="show_advanced_settings = !show_advanced_settings">
+   @click="show_advanced_settings = !show_advanced_settings"
+   role="button"
+   :aria-expanded="show_advanced_settings"
+   :aria-controls="'advanced-settings-content'">
admin/form-builder/assets/js/mixins/form-field.js (1)

9-9: Consider using a more descriptive default value.

The default value { key: 'value' } seems generic. Consider using a more meaningful default that better represents the field structure.

- default: () => ({ key: 'value' })
+ default: () => ({ 
+   name: '',
+   type: 'text',
+   value: ''
+ })
admin/form-builder/assets/js/components/field-visibility/template.php (1)

50-51: Consider extracting checkbox styles to a CSS class

The checkbox styling attributes are repeated multiple times. Consider extracting these to a reusable CSS class to maintain consistency and reduce duplication.

-                    $output .= "<label><input class='wpuf-bg-transparent wpuf-text-white checked:wpuf-bg-transparent checked:wpuf-shadow-primary checked:hover:wpuf-shadow-transparent checked:focus:wpuf-bg-transparent' type='checkbox' v-model='choices' value='{$role}'> {$role_name} </label>";
+                    $checkbox_class = 'wpuf-checkbox wpuf-bg-transparent wpuf-text-white checked:wpuf-bg-transparent checked:wpuf-shadow-primary checked:hover:wpuf-shadow-transparent checked:focus:wpuf-bg-transparent';
+                    $output .= "<label><input class='{$checkbox_class}' type='checkbox' v-model='choices' value='{$role}'> {$role_name} </label>";
admin/form-builder/assets/js/components/form-fields-v4-1/index.js (2)

31-36: Consider using Vue's built-in drag-and-drop directives

While jQuery UI draggable works, consider migrating to Vue's native drag-and-drop directives for better integration with the Vue ecosystem and reduced dependencies.


91-113: Optimize search implementation

The current search implementation has some potential improvements:

  1. Remove unnecessary self alias as arrow functions inherit this
  2. Consider debouncing the search to improve performance
  3. Consider memoizing the filtered results
watch: {
-    searched_fields: function ( searchValue ) {
-        var self = this;
+    searched_fields: _.debounce(function(searchValue) {
         this.set_default_panel_sections();

         if (this.searched_fields === '') {
             return;
         }

-        const matchedFields = Object.keys( self.field_settings ).filter( key =>
-            self.field_settings[key].title.toLowerCase().includes( searchValue.toLowerCase() )
+        const matchedFields = Object.keys(this.field_settings).filter(key =>
+            this.field_settings[key].title.toLowerCase().includes(searchValue.toLowerCase())
         );

-        const updatedStructure = self.panel_sections.map(section => ({
+        const updatedStructure = this.panel_sections.map(section => ({
             id: section.id,
             title: section.title,
             show: section.show,
             fields: section.fields.filter(field => matchedFields.includes(field))
         }));

         this.$store.commit('set_panel_sections', updatedStructure);
-    }
+    }, 300)
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 93-93: 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)

Lib/Appsero/Client.php (1)

168-168: LGTM! Consider documenting parameter meanings.

The explicit parameters true, false for get_plugin_data() make the intention clearer. The first parameter enables HTML markup in the output, while the second disables translation, which is appropriate for this context as the data is used programmatically.

Consider adding a brief comment explaining the parameter choices:

-            $plugin_data = get_plugin_data( $this->file, true, false );
+            // Enable markup but disable translation as data is used programmatically
+            $plugin_data = get_plugin_data( $this->file, true, false );
admin/form-builder/assets/js/components/form-fields-v4-1/template.php (2)

4-10: Enhance accessibility for the search input field.

The search input should include ARIA attributes for better screen reader support.

 <input
     type="text"
     name="search"
     id="search"
     v-model="searched_fields"
+    aria-label="<?php esc_attr_e( 'Search Field', 'wp-user-frontend' ); ?>"
+    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' ); ?>">

52-68: Improve pro feature alert UX.

The pro feature alert should provide more context about the feature's benefits and how to unlock it.

 <div
     v-if="is_pro_feature(field)"
     :data-form-field="field"
     data-source="panel"
-    @click="alert_pro_feature(field)"
+    @click="show_pro_feature_details(field)"
+    role="button"
+    tabindex="0"
+    :aria-label="field_settings[field].title + ' - Pro Feature'"
     class="wpuf-relative wpuf-flex wpuf-items-center wpuf-rounded-lg wpuf-border wpuf-border-gray-200 wpuf-bg-white wpuf-shadow-sm hover:wpuf-border-gray-300 wpuf-p-3">
includes/Fields/Form_Pro_Upgrade_Fields.php (1)

69-69: Replace WPUF_SINCE placeholder with actual version.

The @SInCE tag uses a placeholder constant that should be replaced with the actual version number.

- * @since WPUF_SINCE
+ * @since 4.0.0
includes/Admin/Forms/Post/Templates/Form_Template.php (1)

85-89: Consider extracting version comparison logic.

The version comparison with '4.1' is repeated in multiple places. Consider extracting this into a class constant or method for better maintainability.

 class Form_Template {
+    private const VERSION_THRESHOLD = '4.1';
+    
+    private function is_legacy_version(): bool {
+        return defined('WPUF_PRO_VERSION') && 
+               version_compare(WPUF_PRO_VERSION, self::VERSION_THRESHOLD, '<');
+    }

     public function enqueue_scripts() {
-        if (defined('WPUF_PRO_VERSION') && version_compare(WPUF_PRO_VERSION, '4.1', '<')) {
+        if ($this->is_legacy_version()) {
             wp_enqueue_style('wpuf-form-builder');
         } else {
             wp_enqueue_style('wpuf-admin-form-builder');
         }
     }

Also applies to: 112-118

Gruntfile.js (1)

3-5: Consider using glob patterns for file mapping.

The tailwindFileMap uses hard-coded file paths. Consider using glob patterns for more flexible file matching.

 const tailwindFileMap = {
-    'admin/form-builder/views/form-builder-v4.1.php': 'admin/form-builder.css',
+    'admin/form-builder/views/*.php': 'admin/form-builder.css',
 }
includes/Frontend_Render_Form.php (1)

303-309: LGTM with a minor suggestion for class naming.

The implementation correctly uses printf for localization and proper escaping. However, there's a minor inconsistency in the HTML class naming.

Consider renaming the class from wpuf-items-table-containermessage-box to wpuf-items-message-box for better clarity and consistency:

-<span class="wpuf-items-table-containermessage-box" id="remaining-feature-item">
+<span class="wpuf-items-message-box" id="remaining-feature-item">
📜 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 286a488.

⛔ Files ignored due to path filters (10)
  • assets/images/recaptcha-placeholder.png is excluded by !**/*.png
  • 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
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (82)
  • 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/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 (1 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/template.php (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 (1 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-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 (13 hunks)
  • admin/form-builder/assets/js/mixins/add-form-field.js (1 hunks)
  • admin/form-builder/assets/js/mixins/form-field.js (3 hunks)
  • admin/form-builder/assets/js/mixins/option-field.js (1 hunks)
  • admin/form-builder/assets/less/form-builder.less (0 hunks)
  • admin/form-builder/views/form-builder-v4.1.php (1 hunks)
  • admin/form-builder/views/form-builder.php (2 hunks)
  • assets/css/admin.css (0 hunks)
  • assets/css/frontend-forms.css (1 hunks)
  • assets/js-templates/form-components.php (17 hunks)
  • assets/js/wpuf-form-builder-components.js (8 hunks)
  • assets/js/wpuf-form-builder-mixins.js (5 hunks)
  • assets/js/wpuf-form-builder.js (13 hunks)
  • assets/less/admin.less (0 hunks)
  • assets/less/frontend-forms.less (1 hunks)
  • includes/Admin/Forms/Admin_Form.php (4 hunks)
  • includes/Admin/Forms/Admin_Form_Builder.php (3 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_Cloudflare_Turnstile.php (1 hunks)
  • includes/Fields/Form_Field_Featured_Image.php (1 hunks)
  • includes/Fields/Form_Field_Post_Title.php (2 hunks)
  • includes/Fields/Form_Field_SectionBreak.php (1 hunks)
  • includes/Fields/Form_Field_Textarea.php (1 hunks)
  • includes/Fields/Form_Field_reCaptcha.php (0 hunks)
  • includes/Fields/Form_Pro_Upgrade_Fields.php (2 hunks)
  • includes/Frontend_Render_Form.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 (4)
  • admin/form-builder/assets/less/form-builder.less
  • assets/css/admin.css
  • includes/Fields/Form_Field_reCaptcha.php
  • assets/less/admin.less
✅ Files skipped from review due to trivial changes (7)
  • includes/Admin/template-parts/modal.php
  • includes/Admin/Forms/Post/Templates/Post_Form_Template_Events_Calendar.php
  • includes/Admin/Forms/Post/Templates/Post_Form_Template_WooCommerce.php
  • admin/form-builder/assets/js/components/help-text/template.php
  • admin/form-builder/assets/js/components/form-multiple_select/template.php
  • admin/form-builder/views/form-builder.php
  • includes/Admin/Forms/Post/Templates/Post_Form_Template_Post.php
👮 Files not reviewed due to content moderation or server errors (6)
  • assets/js/wpuf-form-builder-mixins.js
  • admin/form-builder/assets/js/components/form-column_field/index.js
  • includes/Admin/Forms/Admin_Form_Builder.php
  • includes/Fields/Field_Contract.php
  • assets/less/frontend-forms.less
  • assets/css/frontend-forms.css
🧰 Additional context used
🪛 Biome (1.9.4)
admin/form-builder/assets/js/components/form-fields-v4-1/index.js

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 93-93: 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)

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

[error] 334-334: 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] 334-334: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 365-365: 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] 303-303: 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] 1612-1612: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 1635-1635: 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/builder-stage-v4-1/index.js

[error] 146-146: 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] 146-146: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 177-177: 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] 115-115: 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/form-builder.js

[error] 530-530: Shouldn't redeclare 'settings_tabs'. Consider to delete it or rename it.

'settings_tabs' is defined here:

(lint/suspicious/noRedeclare)


[error] 538-538: Shouldn't redeclare 'clipboard'. Consider to delete it or rename it.

'clipboard' is defined here:

(lint/suspicious/noRedeclare)


[error] 541-541: Shouldn't redeclare 'self'. Consider to delete it or rename it.

'self' is defined here:

(lint/suspicious/noRedeclare)

assets/js/wpuf-form-builder.js

[error] 530-530: Shouldn't redeclare 'settings_tabs'. Consider to delete it or rename it.

'settings_tabs' is defined here:

(lint/suspicious/noRedeclare)


[error] 538-538: Shouldn't redeclare 'clipboard'. Consider to delete it or rename it.

'clipboard' is defined here:

(lint/suspicious/noRedeclare)


[error] 541-541: Shouldn't redeclare 'self'. Consider to delete it or rename it.

'self' is defined here:

(lint/suspicious/noRedeclare)

🔇 Additional comments (82)
includes/Admin/Forms/Post/Templates/Pro_Form_Preview_EDD.php (2)

30-30: Good choice upgrading to SVG format!

Switching from PNG to SVG is a good improvement as SVG provides:

  • Better scaling across different screen resolutions
  • Typically smaller file size
  • Crisp rendering on high DPI displays

30-30: Verify the SVG asset exists

Let's ensure the SVG file is properly placed in the assets directory.

✅ Verification successful

SVG asset exists and is properly placed

The SVG file edd.svg is present at the correct location assets/images/templates/edd.svg, matching the path referenced in the code.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence of the SVG file and check for similar template files
# that might need the same update

# Check if the SVG file exists
fd -e svg "edd.svg$" assets/images/templates/

# Look for other template files that might need similar updates
rg -l "\.png'" includes/Admin/Forms/Post/Templates/

Length of output: 204

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

9-9: LGTM! Improved help text semantics and styling

Good improvements:

  • Using <p> instead of <span> is more semantic for help text
  • Utility classes enhance visual hierarchy and maintainability
admin/form-builder/assets/js/components/form-image_upload/template.php (2)

4-6: LGTM! Verify styling consistency across themes.

The new utility-first CSS classes improve maintainability and alignment. The dynamic class binding through builder_class_names provides good flexibility for styling variations.

✅ Verification successful

The results show that the utility classes are consistently used across multiple components in the codebase, including form builder components, subscription components, and Vue templates. The CSS classes are properly defined in the form builder CSS files (src/css/admin/form-builder.css and assets/css/admin/form-builder.css).

Let's verify the actual CSS implementation to ensure proper styling:


Styling implementation is consistent and properly defined

The utility classes are well-implemented with proper CSS definitions in the form builder stylesheets. The classes follow a consistent pattern:

  • wpuf-inline-flex maps to display: inline-flex
  • wpuf-items-center maps to align-items: center
  • Responsive variants are properly handled (e.g., sm:wpuf-items-center)
  • Classes are namespaced with wpuf- prefix to avoid conflicts with themes
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of new CSS classes across components
# and potential style conflicts with WordPress themes

# Check for usage of new utility classes across components
rg -l "wpuf-(inline-flex|items-center|gap-x-1\.5)"

# Check for any existing theme-specific overrides
rg -l "\.wpuf-(inline-flex|items-center|gap-x-1\.5)" --type css

Length of output: 2207


Script:

#!/bin/bash
# Check the CSS implementation of these utility classes
rg "wpuf-(inline-flex|items-center|gap-x-1\.5)" --type css -A 2

Length of output: 672


23-23: Verify sanitization of help text content.

While the semantic change to <p> and styling improvements are good, using v-html with potentially unsanitized content could pose an XSS risk.

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

16-16: Verify the new utility classes

The semantic change from <span> to <p> is good. Let's verify that the new utility classes (wpuf-mt-2, wpuf-text-sm, wpuf-text-gray-500) are properly defined in the CSS.

✅ Verification successful

Utility classes are properly defined and available

The utility classes are correctly defined in the CSS files:

  • wpuf-mt-2 is defined in assets/css/admin/form-builder.css with margin-top: 0.5rem
  • wpuf-text-sm is defined with font-size: 0.875rem and line-height: 1.25rem
  • wpuf-text-gray-500 is defined with the appropriate gray color using RGB values

These classes appear to be part of a well-structured utility-first CSS framework used throughout the codebase, following Tailwind CSS naming conventions. The semantic change and styling are appropriate.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the utility classes are defined in the CSS files

# Search for the utility class definitions
rg -A 2 "wpuf-(mt-2|text-sm|text-gray-500)" admin/form-builder/assets/css/

Length of output: 147


Script:

#!/bin/bash
# Let's try searching in the entire repository for these utility classes
# First, let's find all CSS files
fd -e css -x rg -l "wpuf-(mt-2|text-sm|text-gray-500)" {}

# Also search for any potential SCSS/LESS files that might define these utilities
fd -e scss -e less -x rg -l "wpuf-(mt-2|text-sm|text-gray-500)" {}

# Let's also check if there's a build process that generates these classes
fd -g "package.json" -g "webpack.*.js" -g "tailwind.config.*" -x cat {}

Length of output: 439


Script:

#!/bin/bash
# Let's check the content of the CSS files that matched to see the actual definitions
rg -A 2 "wpuf-(mt-2|text-sm|text-gray-500)" ./src/css/admin/form-builder.css ./assets/css/admin/form-builder.css

# Also let's check if these classes are used elsewhere in the codebase
rg "class=.*wpuf-(mt-2|text-sm|text-gray-500)" 

Length of output: 35756


5-5: Verify the builder_class_names mixin implementation

The changes look good, but let's ensure the new builder_class_names function is properly defined in the wpuf_mixins.form_field_mixin.

Also applies to: 8-8

✅ Verification successful

The changes are correctly implemented and consistent

The verification confirms:

  • The builder_class_names function is properly defined in the form-field mixin with specific handling for textarea fields
  • The :default binding is used correctly in the textarea component
  • The implementation is unique to this textarea component and doesn't require changes elsewhere
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the builder_class_names function implementation
# Search for the mixin definition and its usage across components

# Check for the mixin definition
rg -A 5 "builder_class_names.*function" admin/form-builder/assets/js/

# Check for consistent usage across other field components
ast-grep --pattern 'builder_class_names($$$)' admin/form-builder/assets/js/components/

Length of output: 646


Script:

#!/bin/bash
# Let's check for the complete implementation of builder_class_names function
rg -A 15 'builder_class_names.*function' admin/form-builder/assets/js/mixins/form-field.js

# Check for usage of :default and builder_class_names in textarea field template
cat admin/form-builder/assets/js/components/form-textarea_field/template.php

# Check for any other components using similar pattern
rg -l ':default="field.default"' admin/form-builder/assets/js/components/

Length of output: 1592

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

10-12: LGTM! Consistent class naming implementation.

The changes maintain consistency with other select fields while preserving the existing functionality.


4-6: Verify XSS protection and class naming implementation.

While the class naming centralization is good, using v-html for dropdown options could pose XSS risks if the content isn't properly sanitized.

Let's verify the implementation:

✅ Verification successful

Let me gather more information about the term data handling and builder_class_names implementation:


XSS risk is mitigated through proper term data handling

The implementation shows that the dropdown options are generated from properly structured term objects with controlled properties (id, name, term_id). The data undergoes several safety measures:

  • Terms are filtered and processed through structured methods
  • Values are explicitly parsed as integers where needed
  • Term properties are accessed directly rather than through user input
  • The hierarchy building process uses controlled term properties

Additionally, the builder_class_names appears to be consistently used across multiple components for class binding, suggesting it's a standardized utility.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check the builder_class_names mixin implementation
ast-grep --pattern 'builder_class_names'

# Check if term dropdown options are sanitized
rg -A 5 "get_term_dropdown_options"

Length of output: 5895


Script:

#!/bin/bash
# Check how terms are fetched and processed
rg -A 10 "terms.*=" admin/form-builder/assets/js/components/form-taxonomy/

# Check for escaping/sanitization utilities
rg -A 3 "escape|sanitize|clean" admin/form-builder/assets/js/

# Look for builder_class_names implementation in mixins or utils
rg -A 5 "builder_class_names.*=" admin/form-builder/assets/js/

Length of output: 9913


40-42: Consider adding input validation for the size attribute.

While the dynamic bindings enhance customization, ensure that the field.size value is validated to prevent invalid size values.

Let's check the field validation implementation:

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

7-22: Alignment & spacing are well-structured
The flex layout for showing and syncing values is clean and readable, nicely grouping the checkboxes with their labels. Good job!


36-50: Ensure robust uniqueness for v-for loops
The top-level array iteration on line 38 uses “option.id” as the key. Make sure it’s guaranteed to be unique for each option. If it’s conceivable that “option.id” might be duplicated, consider generating a unique key or using “index” plus “id.”

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

4-5: Nice usage of mixins
Including both general builder-stage mixins and add_form_field mixin ensures well-organized logic.


25-27: Confirm that the pro_link is always available
It’s referencing “wpuf_form_builder.pro_link.” If there’s any chance this variable can be undefined, consider a fallback or a guard to avoid unexpected runtime errors.


30-82: Drag-and-drop logic looks robust
You’re successfully managing droppable areas and column fields. Great use of jQuery UI’s sortable “update” and “over” events.

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

1-4: Responsive design approach looks solid
The wpuf-flex and wpuf-min-w-0 classes effectively ensure the columns adapt to different screen sizes. This is a good use of utility-first classes.


5-21: Drag-and-drop container
The class “wpuf-column-inner-fields” plus “sortable-list” suggests some dynamic reordering. Confirm these items remain fully usable on mobile—some mobile browsers can be tricky with drag-and-drop.


22-41: Check field collision
You’re merging multiple classes (lines 14–20) to compute dynamic classes for each field. Ensure conflicting styles or naming collisions don’t happen if two classes define the same property differently.

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

1-4: Empty state message is helpful
Showing a quick tip (“Add fields by dragging...”) guides new users effectively.


6-20: Improve naming consistency
If “sortable-list” is used in other places, confirm consistent naming in CSS and remove any unused references to avoid confusion.


24-32: Responsive layout
The usage of “wpuf-w-1/4” vs. “wpuf-w-3/4” is consistent with your two-column approach. Great job leveraging utility classes.


50-53: Column field switching
The conditional check “field.input_type === 'column_field'” is a neat approach to toggling multiple layouts. Ensure no references to deprecated type keys remain in other files, especially if “column_field_v2” was used previously.


115-120: Custom submit area
The do_action hook at line 119 is a great way to allow extensibility from external plugins or themes.

admin/form-builder/views/form-builder-v4.1.php (3)

1-4: Ensure Backend Validation or Nonce Checks

The form’s method is “post” and it uses @submit.prevent on the Vue side, but ensure that robust backend validation is also in place beyond the nonce check to prevent unauthorized submissions or tampering.


130-145: Confirm Two-Way Binding Strategy for enableMultistep

“enableMultistep” is a local reactive property. Verify if it needs to be persisted in the Vuex store or in DB settings to maintain the toggle state across sessions or refreshes.


153-154: Check Registration of builder-stage-v4-1 Component

Confirm that the JavaScript registering 'builder-stage-v4-1' is properly enqueued and loaded on this page. Otherwise, the component may fail to render.

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

44-46: Validate is_post_form Logic

You set “is_post_form” by checking both “is_older_form” and post type. Confirm that this logic correctly handles edge cases where forms of different post types might also need the “post form” behavior.


73-73: Ensure editing_field_id Reset is Desired

Resetting “editing_field_id” to 0 when switching to 'form-fields' or 'form-fields-v4-1' might disrupt user flow if the user was in the middle of editing. Confirm that this is the intended user experience.


245-245: Confirm Current Panel Reversion on Field Deletion

When a field is deleted, the code reverts “current_panel” to 'form-fields' or 'form-fields-v4-1.' Confirm whether that is the desired behavior if a user was on “field-options.”


489-525: Check Lifecycle for Post Form Handling

In the mounted hook, the code branches to handle “is_post_form.” Ensure all tab logic, event bindings, and particularly the clipboard code are invoked where needed for non-post forms.

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

44-46: Clarify is_post_form Assignment

Line 45 sets is_post_form using is_older_form and post_type. Make sure this condition is correct for non-legacy forms that might also be “wpuf_forms.”


73-73: Conditional Check for Field-Options

In set_current_panel, the logic sets “editing_field_id = 0” when entering 'form-fields' or 'form-fields-v4-1.' This might disrupt partially updated fields. Double-check if this is expected.


245-245: Confirm UI Flow Upon Deletion

When deleting a field, the code sets “current_panel” to 'form-fields' or 'form-fields-v4-1.' Confirm that returning to that panel after a field removal is consistent with desired UX.


392-392: Return to Panel on Column Field Deletion

Similar to line 245, the logic reverts “current_panel” to a default. Validate if users should remain on “field-options” panel or if the revert is desired.

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

189-216: Introduced builder-stage-v4-1

This new component parallels “builder-stage” with minimal differences. Verify that any optional lifecycle hooks or watchers from the original “builder-stage” are duplicated if needed.


612-612: Check Mixin Suitability in field-options

You have “mixins: [wpuf_mixins.field_options, wpuf_mixins.form_field_mixin].” Ensure that both mixins do not override each other’s behavior inadvertently.

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

283-290: Double-check property bindings for checkboxes.
The panel-field-opt-checkbox logic references options keyed by numeric or string keys. Ensure that v-model usage aligns with the correct key types, especially if future code extends or changes these options.


757-772: Uniform horizontal vs. vertical checkbox layout logic.
You handle inline vs. block checkboxes here. Confirm that your design guidelines or product specs want them to look different from the older implementation or if there’s a chance to unify these approaches to remain consistent.


95-133: Ensure numeric parsing consistency for editing_form_id checks.
You’re calling parseInt on both editing_form_id and field.id. If editing_form_id or field.id can ever be undefined or a non-numeric string, it could lead to NaN comparisons. Confirm that these values are always set to numeric types in the upstream code, or implement defensive checks to avoid potential runtime issues.

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

1-11: Check version comparison for correctness.
The condition checks if WPUF_PRO_VERSION < 4.1. If WPUF_PRO_VERSION is empty or invalid, the else path is triggered. Make sure that’s intended. Sometimes plugin version mismatches can cause unexpected behavior.

✅ Verification successful

Version comparison is correctly implemented and consistently used across the codebase

The version comparison check defined('WPUF_PRO_VERSION') && version_compare(WPUF_PRO_VERSION, '4.1', '<') is consistently implemented across multiple files in the codebase. This pattern is used to:

  • Handle different form builder views and styles
  • Load appropriate templates
  • Manage asset enqueueing

The condition is safe as it:

  1. First checks if the constant is defined before comparing
  2. Consistently uses version 4.1 as the comparison point
  3. Falls back to newer implementations when version is >= 4.1 or when PRO version isn't defined
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Searching for references to WPUF_PRO_VERSION usage across the codebase
rg "WPUF_PRO_VERSION" -A 5

Length of output: 3889

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

7-9: Improved class binding for text fields.
Switching to builder_class_names('textfield') makes it consistent with the new naming convention. Ensure you apply the same approach to all field types for uniform styling, or keep fallback references if older references remain in the codebase.

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

4-9: Leverage hidden field styling for clarity.
Using builder_class_names('text_hidden') aligns with the updated convention. If the “hidden” nature is critical for front-end usage, consider verifying that these fields don’t appear to end users or search engines in actual forms.

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

5-5: LGTM! Verify builder_class_names implementation

The switch to builder_class_names aligns with the form builder UI enhancement objectives and should provide more consistent styling.

✅ Verification successful

LGTM! builder_class_names implementation is correct

The switch from class_names to builder_class_names is properly implemented in the form builder mixins. The method handles textarea fields correctly by applying consistent styling classes including responsive design, text colors, shadows, and borders. The implementation aligns with the UI enhancement objectives.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the builder_class_names method implementation
ast-grep --pattern 'builder_class_names($_)'

Length of output: 46


Script:

#!/bin/bash
# Search for builder_class_names with ripgrep for a broader search
rg "builder_class_names" -A 2 -B 2

# Also search for class_names to understand the pattern
rg "class_names" -A 2 -B 2

Length of output: 54177


Script:

#!/bin/bash
# Search for builder_class_names implementation
ast-grep --pattern 'builder_class_names: function($_) { $$$ }'

# Also search for the implementation with ripgrep for backup
rg "builder_class_names: function" -A 10

Length of output: 1770


Script:

#!/bin/bash
# Get the full implementation of builder_class_names
rg "builder_class_names: function" -A 30 "admin/form-builder/assets/js/mixins/form-field.js"

Length of output: 1448

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

9-9: LGTM! Improved help text structure

Good improvements:

  • Using semantic <p> tag instead of <span>
  • Consistent utility classes for styling
  • Proper spacing with wpuf-mt-2

4-4: Ensure safe class name concatenation

The concatenation of class names could potentially result in invalid class strings if either method returns undefined.

Consider using an array or template literal for safer class concatenation:

-:class="class_names('email') + builder_class_names('text')"
+:class="[class_names('email'), builder_class_names('text')]"
✅ Verification successful

Based on the search results, I found the implementations of both class_names and builder_class_names methods in the codebase. Here's what I found:

  1. class_names method in admin/form-builder/assets/js/mixins/form-field.js returns an array of classes:
class_names: function(type_class) {
    return [
        type_class,
        this.required_class(),
        'wpuf_' + this.field.name + '_' + this.form_id
    ];
}
  1. builder_class_names method in the same file returns common classes based on the type:
builder_class_names: function(type_class) {
    var commonClasses = '';
    switch (type_class) {
        case 'text':
        case 'textfield':
        // ...
    }
}

Since both methods are properly implemented and the concatenation is being used widely across multiple components in the codebase (as seen in the search results), this is a safe pattern that's already established in the project.

No issues with class name concatenation

The concatenation of class_names('email') with builder_class_names('text') is safe as both methods are properly implemented and return valid values. This pattern is consistently used across multiple components in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for class_names and builder_class_names implementations
ast-grep --pattern 'class_names($_)'
ast-grep --pattern 'builder_class_names($_)'

Length of output: 85


Script:

#!/bin/bash
# Search for class_names and builder_class_names function definitions using ripgrep
echo "=== Searching for class_names function ==="
rg -A 5 "class_names\s*=?\s*function" 

echo "=== Searching for builder_class_names function ==="
rg -A 5 "builder_class_names\s*=?\s*function"

echo "=== Searching for Vue component definitions that might contain these methods ==="
rg -A 10 "methods:\s*{" --type js

Length of output: 588


Script:

#!/bin/bash
# Search for class_names and builder_class_names using simpler patterns
echo "=== Searching for class_names usage and definition ==="
rg "class_names" -A 5

echo "=== Searching for builder_class_names usage and definition ==="
rg "builder_class_names" -A 5

echo "=== Searching for Vue methods block ==="
rg "methods: {" -A 10

Length of output: 62549

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

7-7: LGTM! Improved conditional rendering

Good improvements:

  • Using strict comparison (!==)
  • Simplified template structure
  • Clear alt text for accessibility

7-7: Verify WPUF_ASSET_URI constant availability

Ensure the PHP constant is properly defined before template rendering.

✅ Verification successful

WPUF_ASSET_URI constant is properly defined

The constant WPUF_ASSET_URI is defined in the main plugin file wpuf.php as WPUF_ROOT_URI . '/assets'. Since this is defined in the main plugin file, it will be available throughout the plugin's execution, including template files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for WPUF_ASSET_URI constant definition
rg -g '*.php' "define.*WPUF_ASSET_URI"

Length of output: 214


Script:

#!/bin/bash
# Check if wpuf.php is included/required before the template
rg -g '*.php' -B 5 "require.*form-recaptcha/template\.php|include.*form-recaptcha/template\.php"

Length of output: 98


Script:

#!/bin/bash
# Let's check how this template is being loaded and verify the constant's availability
rg -g '*.php' "form-recaptcha/template" -B 5

Length of output: 44

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

1-6: LGTM! UI improvements enhance user experience.

The changes improve the pro feature alert's visual presentation and accessibility through:

  • Proper flexbox layout
  • Clear typography with appropriate text sizes and colors
  • Tooltip implementation for better user feedback
  • Semantic HTML structure
admin/form-builder/assets/js/components/form-post_title/template.php (1)

10-10: LGTM! Semantic markup improvement.

The change from <span> to <p> for help text improves accessibility and semantic structure.

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

11-11: LGTM! Consistent help text implementation.

The help text implementation matches the pattern used in other form components, maintaining consistency in the UI.


4-5: Verify class binding consistency across form components.

Let's check if other form components follow similar patterns.

Also applies to: 7-8

✅ Verification successful

Let me fix the regex and gather more information about class bindings.


Class binding implementation is consistent across form components

The verification shows that class bindings are consistently implemented across the form components:

  1. Form input components consistently use either builder_class_names() or class_names() for dynamic class binding
  2. The Tailwind utility classes are consistently applied, as seen in similar components like post_title and post_tags
  3. The pattern :class="builder_class_names('text')" combined with base Tailwind classes is used consistently for text-like inputs
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check class binding methods and Tailwind classes across form components

# Check for different class binding methods
echo "Checking class binding methods..."
rg -t php "(:class=\"(class_names|builder_class_names)" admin/form-builder/assets/js/components/

# Check for duplicate Tailwind classes
echo "Checking Tailwind utility classes..."
rg -t php "class=\"wpuf-block wpuf-w-full wpuf-rounded-md" admin/form-builder/assets/js/components/

Length of output: 989


Script:

#!/bin/bash
# Description: Check class binding methods and Tailwind classes across form components

# Check for different class binding methods with escaped quotes
echo "Checking class binding methods..."
rg -t php ":class=\".*?\"" admin/form-builder/assets/js/components/

# Check for builder_class_names usage
echo "Checking builder_class_names usage..."
rg -t php "builder_class_names" admin/form-builder/assets/js/components/

# Check for class_names usage
echo "Checking class_names usage..."
rg -t php "class_names" admin/form-builder/assets/js/components/

Length of output: 18339

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

13-13: LGTM: Improved help text structure

Good improvement in semantic HTML by changing from span to p with proper Tailwind utility classes for consistent styling.


4-4: Verify builder_class_names method availability

The change from class_names to builder_class_names and addition of :default_text binding looks good, but let's ensure the builder_class_names method is properly defined.

Also applies to: 6-6

✅ Verification successful

Based on the search results, I can see that the builder_class_names method is properly defined in the form-field mixin at admin/form-builder/assets/js/mixins/form-field.js and is widely used across multiple form components in the codebase. The method is also defined in assets/js/wpuf-form-builder-mixins.js, suggesting it's a core functionality used throughout the form builder.

The change from class_names to builder_class_names appears to be part of a consistent pattern, as both methods exist in the codebase and serve different purposes - class_names for basic class assignments and builder_class_names for builder-specific styling.

The change is valid and properly supported by the codebase

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for builder_class_names method definition
ast-grep --pattern 'builder_class_names'

Length of output: 40


Script:

#!/bin/bash
# Search for builder_class_names using ripgrep for a broader search
rg -i "builder_class_names" -A 3 -B 3

Length of output: 29986


Script:

#!/bin/bash
# Search for class_names (original method) to understand the context
rg -i "class_names" -A 3 -B 3

Length of output: 42098


Script:

#!/bin/bash
# Look for Vue component or mixin definitions that might contain these methods
rg -i "methods:\s*{" -A 10 -B 3

Length of output: 121

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

1-1: LGTM: Improved conditional rendering and styling

Good improvements:

  • Changed to v-if for better performance when the component is rarely toggled
  • Added Tailwind classes for consistent styling

Also applies to: 8-9

✅ Verification successful

z-index hierarchy is consistent with other components

The z-index value of 30 (wpuf-z-30) in the multiselect component aligns with the established pattern in the codebase:

  • Used for dropdown/select components (field-select also uses wpuf-z-30)
  • Higher than overlay elements (wpuf-z-10)
  • Lower than critical UI elements like popups (wpuf-z-50)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for z-index hierarchy in other components
rg "wpuf-z-\d+" --type php --type js

Length of output: 5895

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

1-1: LGTM: Consistent spacing improvements

The addition of utility classes wpuf-mb-6 and wpuf-mt-2 improves the vertical spacing consistency in the form builder UI, aligning with the PR's objective of enhancing the interface.

Also applies to: 6-6


8-8: Verify dynamic class binding implementation

The dynamic class binding using builder_class_names('checkbox') looks good, but let's verify its implementation.

✅ Verification successful

Dynamic class binding implementation is consistent across components

The builder_class_names() method is consistently used across multiple form field components for class binding, including:

  • Checkbox fields (both in form-builder and form-components)
  • Text fields
  • Textarea fields
  • Select fields
  • URL fields
  • Email fields
  • Upload buttons
  • Hidden fields

The implementation follows a consistent pattern where builder_class_names() is used with specific field type identifiers ('checkbox', 'text', 'textareafield', etc.) to generate appropriate class names.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for builder_class_names mixin/method definition
ast-grep --pattern 'builder_class_names($_) {
  $$$
}'

# Search for any existing usage patterns
rg 'builder_class_names\(' -A 2

Length of output: 14123

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

13-13: LGTM: Improved help text presentation

The help text implementation with semantic HTML (<p>) and appropriate styling classes improves readability and accessibility.

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

5-6: Verify mixin dependencies and functionality

The addition of form_field_mixin looks good, but let's verify its implementation and any potential conflicts with option_field_mixin.

✅ Verification successful

Based on the shell script results, I can now generate the final response:

The mixin combination is safe to use

The code inspection shows that:

  • Both mixins have different concerns and non-overlapping props:
    • option_field_mixin uses option_field prop
    • form_field_mixin uses field prop
  • This mixin combination is already used successfully in other components like:
    • field-checkbox/index.js
    • field-option-data/index.js
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for mixin definitions
ast-grep --pattern 'wpuf_mixins = {
  $$$
}'

# Check for any potential naming conflicts in methods
rg -g '*.js' 'form_field_mixin|option_field_mixin' -A 5

Length of output: 28098

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

2-8: LGTM: Regular section break implementation

The regular section break implementation is well-structured with clear semantic HTML and proper use of Tailwind classes for styling.

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

5-6: LGTM: Mixin addition enhances field functionality

The addition of form_field_mixin alongside the existing option_field_mixin is appropriate and aligns with the PR's objective of enhancing field options functionality.

Let's verify the mixin implementation across other field components:

✅ Verification successful

Let me verify the mixin implementation further by checking the actual usage pattern in these files.


Let me check one more pattern to ensure we catch all mixin implementations, as the previous regex might have been too strict.


Mixin implementation is consistent across field components

The verification shows that form_field_mixin is consistently implemented alongside option_field_mixin in field components like checkbox, text, and option-data. The pattern of using both mixins together demonstrates a coherent approach to enhancing field functionality across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for consistent mixin usage across field components
rg -l "wpuf_mixins.form_field_mixin" admin/form-builder/assets/js/components/field-*

Length of output: 1023


Script:

#!/bin/bash
# Check the mixin implementation pattern in the matched files
rg "mixins: \[.*wpuf_mixins.form_field_mixin.*\]" -A 2 admin/form-builder/assets/js/components/field-*

Length of output: 1073


Script:

#!/bin/bash
# Check for mixin declarations with more flexible pattern
rg "mixins.*\[" -A 2 admin/form-builder/assets/js/components/field-checkbox/index.js admin/form-builder/assets/js/components/field-text/index.js admin/form-builder/assets/js/components/field-option-data/index.js admin/form-builder/assets/js/components/field-options/index.js

Length of output: 1415

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

2-13: LGTM: Enhanced image insertion UI

The image insertion implementation is well-structured with good visual feedback through the SVG icon and proper Tailwind styling.

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

4-5: LGTM: Enhanced button styling with Tailwind CSS

The new classes improve button alignment and spacing while maintaining consistency with modern UI practices.


19-19: LGTM: Improved help text presentation

The help text styling is now more consistent with modern UI practices using Tailwind's utility classes.

includes/Fields/Form_Field_SectionBreak.php (1)

92-92: LGTM: New divider property added

The addition of the 'divider' property with 'regular' value aligns with the PR objective of enhancing field options.

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

2-7: LGTM: Improved field label layout

The new flex container with proper spacing and font styling enhances readability and maintains consistency with modern UI patterns.


9-21: LGTM: Enhanced radio button styling

The radio button implementation follows best practices:

  • Proper label association
  • Consistent spacing with gap utilities
  • Clear visual hierarchy with font styling
admin/form-builder/assets/js/components/field-option-data/index.js (1)

9-10: Verify mixin integration impact

The addition of form_field_mixin alongside option_field_mixin could potentially cause conflicts in method overrides or property definitions.

✅ Verification successful

No conflicts found between form_field_mixin and option_field_mixin

After analyzing both mixins, they serve different purposes and have distinct, non-overlapping functionality:

  • form_field_mixin provides common form field rendering functionality (class names, required status)
  • option_field_mixin handles option field settings and dependencies

The mixins have different:

  • Props (field vs option_field and editing_form_field)
  • Computed properties (no overlaps)
  • Methods (unique to each mixin's purpose)

Their combination in the field-option-data component is appropriate as it needs both form field rendering capabilities and option field handling.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for mixin definitions and potential conflicts
echo "Searching for mixin definitions..."
rg -A 10 "form_field_mixin\s*=\s*{" 

echo "Checking for potential method conflicts between mixins..."
rg -A 5 "methods:\s*{" admin/form-builder/assets/js/mixins/

Length of output: 503


Script:

#!/bin/bash
# Search for mixin definitions with fixed regex
echo "Searching for form_field_mixin definition..."
rg "form_field_mixin.*=" -A 10

echo "Searching for option_field_mixin definition..."
rg "option_field_mixin.*=" -A 10

echo "Checking methods in mixins directory..."
find admin/form-builder/assets/js/mixins/ -type f -exec cat {} \;

Length of output: 14210

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

7-7: Verify integration of form_field_mixin

The addition of form_field_mixin to the mixins array enhances the field options component with additional field manipulation capabilities. However, we should verify that all required methods from the mixin are properly integrated.

✅ Verification successful

Let me try a different approach to find the mixin definition and potential method conflicts. I've modified the search patterns to be more precise and avoid regex parsing errors. This will help us verify:

  1. Where form_field_mixin is defined
  2. What methods exist in the field-options component
  3. Where wpuf_mixins is defined and what it contains

I found the location of form_field_mixin. Let's examine its contents and the methods in both mixins to verify proper integration and check for any potential conflicts.


I've found the form_field_mixin implementation which provides utility methods for field manipulation (class names, required status, selection state). Let's examine the field-options component and the field_options mixin to ensure there are no method conflicts and verify proper integration.


Integration of form_field_mixin is properly implemented

The form_field_mixin is correctly integrated into the field-options component. The mixin provides utility methods for field manipulation (class_names, required_class, is_selected) and computed properties (form_id, has_options) that complement the component's existing functionality without any conflicts. The component's own computed properties and methods operate on different concerns, focusing on field settings and editing state management.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for form_field_mixin definition and its methods
ast-grep --pattern 'const form_field_mixin = {
  $$$
}'

# Search for any potential method conflicts
rg -A 2 "methods: {" admin/form-builder/assets/js/components

Length of output: 204


Script:

#!/bin/bash
# Search for form_field_mixin definition
rg "form_field_mixin\s*=" admin/form-builder/assets/js/

# Search for method definitions in field-options component
rg "methods:\s*{" admin/form-builder/assets/js/components/field-options/ -A 5

# Search for wpuf_mixins object definition
rg "wpuf_mixins\s*=" admin/form-builder/assets/js/

Length of output: 361


Script:

#!/bin/bash
# Get the content of form-field mixin
cat admin/form-builder/assets/js/mixins/form-field.js

# Search for methods in field-options component with fixed regex
rg "methods: {" admin/form-builder/assets/js/components/field-options/index.js -A 10

# Search for field_options mixin definition
rg "field_options" admin/form-builder/assets/js/mixins/ -A 5

Length of output: 2961


Script:

#!/bin/bash
# Try different approach to get methods from field-options component
cat admin/form-builder/assets/js/components/field-options/index.js

# Search for field_options mixin with different pattern
cat admin/form-builder/assets/js/mixins/field-options.js

Length of output: 3874

includes/Fields/Form_Field_Post_Title.php (2)

97-97: LGTM: Adding required to default options

Adding 'required' to the default options settings is appropriate as post titles are essential for content management.


113-113: Verify impact of making post title required

Setting required => 'yes' enforces post title as mandatory. While this makes sense for content management, we should verify the impact on existing forms.

✅ Verification successful

Based on the search results, I can now provide a final response:

Making post title required is safe and aligned with existing implementation

The codebase search reveals that:

  • Post title is already set as required in the default form template (wpuf-functions.php: 'required' => 'yes')
  • All form templates (WooCommerce, Events Calendar, Post) consistently implement post title as required
  • No existing forms have required => no for post title (confirmed by empty results from the search)
  • The field is a core WordPress requirement for content management
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for existing forms that might be affected
rg -l "post_title.*required.*no" --type php

# Check for any custom handling of post title validation
ast-grep --pattern 'function validate_post_title($$$)'

Length of output: 102


Script:

#!/bin/bash
# Let's search for any usage of post_title field in forms or configurations
rg -A 3 "post_title" --type php

# Also check for any form validation or processing related to post titles
rg -A 3 "validate.*post.*title" --type php -i

# Look for any form field configurations
ast-grep --pattern 'class Form_Field_Post_Title {
  $$$
}'

Length of output: 44742

includes/Fields/Form_Field_Cloudflare_Turnstile.php (1)

41-48: LGTM! Improved HTML structure and accessibility.

The changes enhance the field's structure by:

  1. Adding proper list item wrapping for consistency with other form fields
  2. Including dynamic attributes via print_list_attributes()
  3. Adding the wpuf-fields class for consistent styling
includes/Fields/Form_Field_Featured_Image.php (1)

113-113: LGTM! Verify impact on existing forms.

The exclusion of the 'width' option from default settings is logical for featured images, as their dimensions are typically managed by the theme.

Let's verify that this change doesn't affect existing forms:

✅ Verification successful

Based on the search results, I can now generate the final response. The results show that in all template implementations (WooCommerce, Post, and Events Calendar), the featured image field is configured without any width settings. The templates only use basic configurations like 'count', 'required', 'label', 'max_size', etc. This confirms that the width parameter is not being used in any existing forms or templates.

Verified: Width parameter exclusion is safe

The removal of the 'width' option from default settings is safe as none of the existing form templates or implementations utilize width configurations for featured images. This change aligns with the typical behavior where featured image dimensions are managed by the theme.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any form configurations that might be using width settings for featured images
rg -l "featured_image.*width" --type php

Length of output: 42


Script:

#!/bin/bash
# Let's try a broader search to find featured image field usage patterns
rg -l "featured_image" --type php

# Also search for any width-related configurations in form fields
rg "width.*featured" --type php -B2 -A2

# Check the parent class or interface for any width-related configurations
fd "Field.php" --type f --exec rg -l "width" {}

Length of output: 797


Script:

#!/bin/bash
# Let's check the actual implementation and usage of featured image field in templates
rg -A 5 "featured_image" includes/Admin/Forms/Post/Templates/*.php

# Check if there are any existing form configurations with featured image settings
rg -A 5 "featured_image" "includes/Fields/Form_Field_Featured_Image.php"

# Look for any width-related configurations in the field manager
rg "width" includes/class-field-manager.php -A 3

Length of output: 5728

includes/Fields/Form_Field_Textarea.php (1)

79-79: Verify the builder_class_names mixin function.

The code uses a Vue.js mixin function that needs to be verified for proper initialization and error handling.

✅ Verification successful

The builder_class_names mixin function is properly implemented and safe to use.

The function is a well-structured utility that:

  • Takes a type_class parameter to determine which CSS classes to apply
  • Has proper switch-case handling for different field types
  • Returns a consistent array of classes including field type, required status, and unique identifier
  • Uses defensive coding with proper variable initialization
  • Has no error-prone operations that would require explicit error handling
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the builder_class_names mixin function implementation

# Search for the mixin definition
ast-grep --pattern 'builder_class_names: function($_) {
  $$$
}'

# Search for any error handling related to the mixin
rg -A 5 "builder_class_names.*error"

Length of output: 105


Script:

#!/bin/bash
# Let's try different approaches to locate the mixin

# Search for builder_class_names in JavaScript/Vue files
rg -t js -t vue "builder_class_names" -B 2 -A 5

# Search for mixins that might contain this function
rg -t js -t vue "mixins.*builder" -B 2 -A 5

# Look for Vue component definitions that might use this
ast-grep --pattern 'Vue.component($_, {
  $$$
  mixins: $_,
  $$$
})'

# Search for any file containing builder_class_names
fd -t f -E node_modules -E vendor | xargs grep -l "builder_class_names"

Length of output: 74083


Script:

#!/bin/bash
# Let's try a different approach to locate the mixin

# Search for builder_class_names in all files
rg "builder_class_names" -B 2 -A 2

# Search for mixins definition files
fd -t f -E node_modules -E vendor "mixins?.js$"

# Look for Vue mixins that might contain this function
ast-grep --pattern 'mixins: {
  $$$
  builder_class_names: $_,
  $$$
}'

Length of output: 22456


Script:

#!/bin/bash
# Let's check the implementation of builder_class_names in the mixins file

# Display the builder_class_names function implementation
rg -A 10 "builder_class_names: function" assets/js/wpuf-form-builder-mixins.js

# Also check the implementation in the form-field mixin
rg -A 10 "builder_class_names: function" admin/form-builder/assets/js/mixins/form-field.js

Length of output: 865


Script:

#!/bin/bash
# Let's see the complete implementation of the builder_class_names function

# Display more context of the function implementation
rg -A 30 "builder_class_names: function" assets/js/wpuf-form-builder-mixins.js

# Also check if there are any error handling related code
rg "commonClasses.*error" assets/js/wpuf-form-builder-mixins.js

Length of output: 1502

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

19-19: Verify the impact of commenting out the action hook.

The admin_footer action hook for rendering post form templates has been commented out. This could affect the form template rendering functionality.

✅ Verification successful

Let me gather more context about where this template rendering might be handled now.


Let me check one more thing to see if this template rendering is moved to a different hook or if it's being handled differently in newer versions.


The commented action hook is part of version-specific changes and is handled correctly

The code shows that the template rendering functionality is part of a broader version-specific change where different templates and styles are loaded based on the WPUF Pro version (before/after 4.1). The commented-out action hook is intentional as the template rendering is now handled through a different mechanism in newer versions, as evidenced by the version-specific modal template loading:

if ( defined( 'WPUF_PRO_VERSION' ) && version_compare( WPUF_PRO_VERSION, '4.1', '<' ) ) {
    $modal = WPUF_ROOT . '/includes/Admin/template-parts/modal.php';
} else {
    $modal = WPUF_ROOT . '/includes/Admin/template-parts/modal-v4.1.php';
}
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the template rendering is handled elsewhere
rg -A 5 "render_post_form_templates" --type php

Length of output: 1106


Script:

#!/bin/bash
# Check for other potential places where this template rendering is hooked or called
rg -A 5 "admin_footer.*template" --type php

# Check the should_display method to understand the conditions
ast-grep --pattern 'function should_display() {
  $$$
}'

# Check if there are any other template rendering hooks in the same class
ast-grep --pattern 'class Form_Template {
  $$$
}'

Length of output: 706


Script:

#!/bin/bash
# Check for any modal or template rendering in the file
rg -B 5 -A 10 "modal" includes/Admin/Forms/Post/Templates/Form_Template.php

# Check if there are any version-specific changes around template rendering
rg "WPUF_PRO_VERSION" --type php -B 2 -A 2

Length of output: 4383

includes/Admin/Menu.php (1)

119-134: LGTM with a path verification suggestion.

The implementation properly handles templates and includes proper error handling with early breaks.

Let's verify the template file existence and permissions:

✅ Verification successful

Template file verification successful

The template file modal-v4.1.php exists at the expected path includes/Admin/template-parts/ and has proper read permissions, confirming that the file inclusion in the code is valid and secure.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify template file existence and permissions

# Check if the template file exists and is readable
fd -t f "modal-v4.1.php" -x sh -c '
  if [ -r "{}" ]; then
    echo "Template file {} exists and is readable"
  else
    echo "Warning: Template file {} is not accessible"
  fi
'

Length of output: 262

includes/Assets.php (1)

109-179: LGTM with asset verification suggestion.

The style registrations are well-organized with consistent formatting and proper versioning.

Let's verify the existence of the new admin form builder CSS file:

✅ Verification successful

The admin form builder CSS file exists in multiple locations

The file form-builder.css exists in both the expected locations:

  • assets/css/admin/form-builder.css (matches the registered path WPUF_ASSET_URI . '/css/admin/form-builder.css')
  • assets/css/wpuf-form-builder.css (matches the registered path WPUF_ASSET_URI . '/css/wpuf-form-builder.css')

The style registrations in the code are correctly referencing existing CSS files in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify existence of the new admin form builder CSS file

# Check if the CSS file exists and is readable
fd -t f "form-builder.css" -p "css/admin" -x sh -c '
  if [ -r "{}" ]; then
    echo "Admin form builder CSS file {} exists and is readable"
  else
    echo "Warning: Admin form builder CSS file {} is not accessible"
  fi
'

Length of output: 318


Script:

#!/bin/bash
# Let's try a broader search for the form-builder CSS file
fd -t f "form-builder.css" -x sh -c '
  echo "Found: {}"
  echo "Path relative to repo root: {//}"
'

# Also search in assets directory which is common for WordPress plugins
fd -t f "form-builder.css" -p "assets" -x sh -c '
  echo "Found in assets: {}"
'

Length of output: 537

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

199-219: LGTM: Well-structured tab content implementation with Vue.js

The implementation correctly uses Vue.js v-show directives to handle tab content visibility, with proper ID matching and secure file inclusion.


237-254: LGTM: Well-implemented tab navigation with Vue.js

The tab navigation implementation demonstrates good practices:

  • Consistent use of Vue.js class bindings for active state
  • Proper internationalization with translation functions
  • Clean and consistent HTML structure

290-292: LGTM: Clean notification tab content implementation

The notification tab content implementation is consistent with other tabs and properly uses Vue.js directives.

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

44-48: LGTM: Clean checkbox input enhancement

The addition of the wpuf-input-checkbox class improves styling consistency while maintaining proper security practices with escaping.

includes/Admin/Posting.php (2)

25-25: LGTM: Proper action hook registration

The action hook is correctly registered for asset management.


63-68: LGTM: Clean version-based style enqueuing

The implementation correctly handles different versions for form builder style enqueuing.

@@ -1,10 +1,10 @@
<div class="wpuf-fields">
<input
type="url"
:class="class_names('url')"
:class="builder_class_names('url')"
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Migration to builder_class_names is incomplete

The codebase shows inconsistent usage of class naming utilities:

  • Several components still use the old class_names method:
    • form-radio_field/template.php: class_names('radio_btns')
    • form-post_title/template.php: class_names('textfield')
    • form-multiple_select/template.php: class_names('multi_label')
    • form-dropdown_field/template.php: class_names('select_lbl')
    • form-checkbox_field/template.php: class_names('checkbox_btns')

The migration to builder_class_names appears to be in progress but not fully completed. This inconsistency could lead to styling issues or maintenance problems.

🔗 Analysis chain

Verify the builder_class_names utility

The change from class_names to builder_class_names appears to be part of a form builder specific refactoring.

Let's verify this utility is consistently used across other form components:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for both old and new class binding methods to ensure consistent migration
echo "Checking for old class_names usage:"
rg "class_names\(" "admin/form-builder"

echo -e "\nChecking for new builder_class_names usage:"
rg "builder_class_names\(" "admin/form-builder"

Length of output: 6563

Comment on lines +14 to +16
<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>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor duplicate SVG code.

The SVG icon is duplicated in both conditional branches. Consider extracting it into a reusable template.

Create a new template for the icon:

+<template #icon>
+  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="wpuf-size-5" role="img" aria-hidden="true">
+    <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>
+</template>

-<template v-if="field.button_label === ''">
-  <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>
+<template v-if="field.button_label === ''">
+  <slot name="icon"></slot>
   <?php _e( 'Select Image', 'wp-user-frontend' ); ?>
 </template>
 <template v-else>
-  <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>
+  <slot name="icon"></slot>
   {{ field.button_label }}
 </template>

Committable suggestion skipped: line range outside the PR's diff.

autocomplete="off"
>
<span v-if="field.help" class="wpuf-help" v-html="field.help" />
<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.

🛠️ Refactor suggestion

Improve help text security while maintaining enhanced styling.

The semantic HTML and utility classes are good improvements, but using v-html for help text could pose XSS risks. Consider using v-text or interpolation ({{ }}) if the help text doesn't require HTML rendering.

-    <p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
+    <p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-text="field.help"></p>
📝 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
<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-text="field.help"></p>

Comment on lines +489 to +525
if ( this.is_post_form ) {
// secondary settings tabs and their contents
var settings_tabs = $( '#wpuf-form-builder-settings-tabs .nav-tab' );
var self = this;

// secondary settings tabs and their contents
var settings_tabs = $('#wpuf-form-builder-settings .nav-tab'),
settings_tab_contents = $('#wpuf-form-builder-settings .tab-contents .group');
// add a click listener to each settings_tab
settings_tabs.each( function () {
$( this ).bind( 'click', self.setActiveSettingsTab );
} );

settings_tabs.first().addClass('nav-tab-active');
settings_tab_contents.first().addClass('active');
var clipboard = new window.Clipboard( '.form-id' );
$( ".form-id" ).tooltip();

this.bind_tab_on_click(settings_tabs, '#wpuf-form-builder-settings');
clipboard.on( 'success', function ( e ) {
// Show copied tooltip
$( e.trigger )
.attr( 'data-original-title', 'Shortcode copied!' )
.tooltip( 'show' );

var clipboard = new window.Clipboard('.form-id');
$(".form-id").tooltip();
self.shortcodeCopied = true;

var self = this;
// Reset the copied tooltip
setTimeout( function () {
$( e.trigger ).tooltip( 'hide' )
.attr( 'data-original-title', self.i18n.copy_shortcode );
self.shortcodeCopied = false;
}, 1000 );

clipboard.on('success', function(e) {
// Show copied tooltip
$(e.trigger)
.attr('data-original-title', 'Copied!')
.tooltip('show');
e.clearSelection();
} );

// Reset the copied tooltip
setTimeout(function() {
$(e.trigger).tooltip('hide')
.attr('data-original-title', self.i18n.copy_shortcode);
}, 1000);
window.onbeforeunload = function () {
if (self.isDirty) {
return self.i18n.unsaved_changes;
}
};
} else {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid Redefining Variables (settings_tabs, clipboard, self)

The snippet re-declares local variables (like “settings_tabs,” “clipboard,” “self”) inside the block for “is_post_form.” This might conflict with earlier variable declarations. Consider unique variable names or block scoping.

- var settings_tabs = ...
- var clipboard = ...
- var self = this;
+ var post_form_settings_tabs = ...
+ var post_form_clipboard = ...
+ var vm = this;
📝 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
if ( this.is_post_form ) {
// secondary settings tabs and their contents
var settings_tabs = $( '#wpuf-form-builder-settings-tabs .nav-tab' );
var self = this;
// secondary settings tabs and their contents
var settings_tabs = $('#wpuf-form-builder-settings .nav-tab'),
settings_tab_contents = $('#wpuf-form-builder-settings .tab-contents .group');
// add a click listener to each settings_tab
settings_tabs.each( function () {
$( this ).bind( 'click', self.setActiveSettingsTab );
} );
settings_tabs.first().addClass('nav-tab-active');
settings_tab_contents.first().addClass('active');
var clipboard = new window.Clipboard( '.form-id' );
$( ".form-id" ).tooltip();
this.bind_tab_on_click(settings_tabs, '#wpuf-form-builder-settings');
clipboard.on( 'success', function ( e ) {
// Show copied tooltip
$( e.trigger )
.attr( 'data-original-title', 'Shortcode copied!' )
.tooltip( 'show' );
var clipboard = new window.Clipboard('.form-id');
$(".form-id").tooltip();
self.shortcodeCopied = true;
var self = this;
// Reset the copied tooltip
setTimeout( function () {
$( e.trigger ).tooltip( 'hide' )
.attr( 'data-original-title', self.i18n.copy_shortcode );
self.shortcodeCopied = false;
}, 1000 );
clipboard.on('success', function(e) {
// Show copied tooltip
$(e.trigger)
.attr('data-original-title', 'Copied!')
.tooltip('show');
e.clearSelection();
} );
// Reset the copied tooltip
setTimeout(function() {
$(e.trigger).tooltip('hide')
.attr('data-original-title', self.i18n.copy_shortcode);
}, 1000);
window.onbeforeunload = function () {
if (self.isDirty) {
return self.i18n.unsaved_changes;
}
};
} else {
if ( this.is_post_form ) {
// secondary settings tabs and their contents
var post_form_settings_tabs = $( '#wpuf-form-builder-settings-tabs .nav-tab' );
var vm = this;
// add a click listener to each settings_tab
post_form_settings_tabs.each( function () {
$( this ).bind( 'click', vm.setActiveSettingsTab );
} );
var post_form_clipboard = new window.Clipboard( '.form-id' );
$( ".form-id" ).tooltip();
post_form_clipboard.on( 'success', function ( e ) {
// Show copied tooltip
$( e.trigger )
.attr( 'data-original-title', 'Shortcode copied!' )
.tooltip( 'show' );
vm.shortcodeCopied = true;
// Reset the copied tooltip
setTimeout( function () {
$( e.trigger ).tooltip( 'hide' )
.attr( 'data-original-title', vm.i18n.copy_shortcode );
vm.shortcodeCopied = false;
}, 1000 );
e.clearSelection();
} );
window.onbeforeunload = function () {
if (vm.isDirty) {
return vm.i18n.unsaved_changes;
}
};
} else {

Comment on lines +206 to +279
<div v-if="hidden_fields.length" class="wpuf-border-t wpuf-border-dashed wpuf-border-gray-300 wpuf-mt-2">
<h4><?php esc_html_e( 'Hidden Fields', 'wp-user-frontend' ); ?></h4>
<ul class="wpuf-form">
<li
v-for="(field, index) in hidden_fields"
class="field-items wpuf-group hover:wpuf-bg-green-50 !wpuf-m-0 !wpuf-p-0"
>
<div
:class="parseInt(editing_form_id) === parseInt(field.id) ? 'wpuf-border wpuf-border-dashed wpuf-bg-green-50 wpuf-border-green-400' : 'wpuf-border-transparent'"
class="wpuf-flex wpuf-bg-gray-50 wpuf-p-4 wpuf-rounded-t-md wpuf-border-t wpuf-border-r wpuf-border-l group-hover:wpuf-border-dashed group-hover:wpuf-border-green-400 group-hover:wpuf-cursor-pointer">
<strong><?php esc_html_e( 'key', 'wp-user-frontend' ); ?></strong>: {{ field.name }} |
<strong><?php esc_html_e( 'value', 'wp-user-frontend' ); ?></strong>: {{ field.meta_value }}
</div>
<div
class="control-buttons wpuf-opacity-0 group-hover:wpuf-opacity-100 wpuf-rounded-b-lg !wpuf-bg-green-600 wpuf-flex wpuf-justify-around wpuf-items-center wpuf-transition wpuf-duration-150 wpuf-ease-out">
<div class="wpuf-flex wpuf-items-center wpuf-text-green-200">
<template v-if="!is_failed_to_validate(field.template)">
<span
:class="action_button_classes"
@click="open_field_settings(field.id)">
<i
class="fa fa-pencil"></i>
Edit
</span>
<span
:class="action_button_classes"
@click="clone_field(field.id, index)">
<i
class="fa fa-clone"></i>
Copy
</span>
</template>
<template v-else>
<span :class="action_button_classes">
<i class="fa fa-arrows control-button-disabled wpuf--ml-1 wpuf-rounded-l-md"></i>
</span>
<span :class="action_button_classes">
<i class="fa fa-pencil control-button-disabled wpuf--ml-1"></i>
Edit
</span>
<span :class="action_button_classes">
<i
class="fa fa-clone control-button-disabled wpuf--ml-1"></i>
Copy
</span>
</template>
<span :class="action_button_classes" @click="delete_field(index)">
<i
class="fa fa-trash-o wpuf--ml-1"></i>
Remove
</span>
<span
v-if="is_pro_feature(field.template)"
:class="action_button_classes" class="hover:wpuf-bg-green-700">
<a
:href="pro_link"
target="_blank"
class="wpuf-rounded-r-md hover:wpuf-bg-slate-500 hover:wpuf-cursor-pointer wpuf-transition wpuf-duration-150 wpuf-ease-out hover:wpuf-transition-all">
<svg
width="15" height="15" viewBox="0 0 20 15" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M19.2131 4.11564C19.2161 4.16916 19.2121 4.22364 19.1983 4.27775L17.9646 10.5323C17.9024 10.7741 17.6796 10.9441 17.4235 10.9455L10.0216 10.9818H10.0188H2.61682C2.35933 10.9818 2.13495 10.8112 2.07275 10.5681L0.839103 4.29542C0.824897 4.23985 0.820785 4.18385 0.824374 4.12895C0.34714 3.98269 0 3.54829 0 3.03636C0 2.40473 0.528224 1.89091 1.17757 1.89091C1.82692 1.89091 2.35514 2.40473 2.35514 3.03636C2.35514 3.39207 2.18759 3.71033 1.92523 3.92058L3.46976 5.43433C3.86011 5.81695 4.40179 6.03629 4.95596 6.03629C5.61122 6.03629 6.23596 5.7336 6.62938 5.22647L9.1677 1.95491C8.95447 1.74764 8.82243 1.46124 8.82243 1.14545C8.82243 0.513818 9.35065 0 10 0C10.6493 0 11.1776 0.513818 11.1776 1.14545C11.1776 1.45178 11.0526 1.72982 10.8505 1.93556L10.8526 1.93811L13.3726 5.21869C13.7658 5.73069 14.3928 6.03636 15.0499 6.03636C15.6092 6.03636 16.1351 5.82451 16.5305 5.43978L18.0848 3.92793C17.8169 3.71775 17.6449 3.39644 17.6449 3.03636C17.6449 2.40473 18.1731 1.89091 18.8224 1.89091C19.4718 1.89091 20 2.40473 20 3.03636C20 3.53462 19.6707 3.9584 19.2131 4.11564ZM17.8443 12.6909C17.8443 12.3897 17.5932 12.1455 17.2835 12.1455H2.77884C2.46916 12.1455 2.21809 12.3897 2.21809 12.6909V14C2.21809 14.3012 2.46916 14.5455 2.77884 14.5455H17.2835C17.5932 14.5455 17.8443 14.3012 17.8443 14V12.6909Z"
fill="#FB9A28"/>
</svg>
</a>
</span>
</div>
</div>
</li>
</ul>
</div>
<?php do_action( 'wpuf_form_builder_template_builder_stage_bottom_area' ); ?>
</div>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Alert on large template complexity.
This hidden field listing block is quite verbose. Consider splitting large Vue structures into smaller sub-components for readability and maintainability. A dedicated “WPUFHiddenField” component might better isolate the logic.

Comment on lines +100 to +102
if ( file_exists( $crown_icon ) ) {
printf( '<span class="pro-icon-title wpuf-ml-2"> %s</span>', file_get_contents( $crown_icon ) );
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security: Avoid direct file_get_contents for SVG.

Using file_get_contents directly on SVG files could pose a security risk. Consider using WordPress's built-in SVG handling or sanitizing the SVG content.

-if (file_exists($crown_icon)) {
-    printf('<span class="pro-icon-title wpuf-ml-2"> %s</span>', file_get_contents($crown_icon));
-}
+if (file_exists($crown_icon)) {
+    $svg_content = file_get_contents($crown_icon);
+    $safe_svg = wp_kses(
+        $svg_content,
+        array(
+            'svg' => array('class' => true, 'viewbox' => true),
+            'path' => array('d' => true)
+        )
+    );
+    printf('<span class="pro-icon-title wpuf-ml-2"> %s</span>', $safe_svg);
+}

Also applies to: 113-115

Comment on lines +130 to +168
<script type="text/javascript">
( function ( $ ) {
var popup = {
init: function () {
$( '.wrap' ).on( 'click', 'a.page-title-action.add-form', this.openModal );
$( '.wpuf-form-template-modal .wpuf-close-btn' ).on( 'click', $.proxy( this.closeModal, this ) );

$( 'body' ).on( 'keydown', $.proxy( this.onEscapeKey, this ) );
},

openModal: function ( e ) {
e.preventDefault();

$( '.wpuf-form-template-modal' ).show();
$( '#wpbody-content .wrap' ).hide();
},

onEscapeKey: function ( e ) {
if (27 === e.keyCode) {
this.closeModal( e );
}
},

closeModal: function ( e ) {
if (typeof e !== 'undefined') {
e.preventDefault();
}

$( '.wpuf-form-template-modal' ).hide();
$( '#wpbody-content .wrap' ).show();
}
};

$( function () {
popup.init();
} );

} )( jQuery );
</script>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider moving JavaScript to a separate file.

The JavaScript code should be moved to a separate file and enqueued properly using WordPress's wp_enqueue_script() for better maintainability and caching.

Comment on lines +285 to +301
grunt.registerTask('tailwind', function() {
const done = this.async();

// Process each file mapping
Object.entries(tailwindFileMap).forEach(([phpFile, cssFile]) => {
const inputFile = `src/css/${cssFile}`;
const outputFile = `assets/css/${cssFile}`;

// Ensure the input file exists
if (grunt.file.exists(inputFile)) {
// Run the tailwind command
grunt.task.run(`shell:tailwind:${inputFile}:${outputFile}`);
}
});

done();
});
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for Tailwind processing.

The Tailwind task should include error handling and logging for better debugging capabilities.

 grunt.registerTask('tailwind', function() {
     const done = this.async();
+    let hasErrors = false;
 
     Object.entries(tailwindFileMap).forEach(([phpFile, cssFile]) => {
         const inputFile = `src/css/${cssFile}`;
         const outputFile = `assets/css/${cssFile}`;
 
         if (grunt.file.exists(inputFile)) {
             grunt.task.run(`shell:tailwind:${inputFile}:${outputFile}`);
+        } else {
+            grunt.log.error(`Input file ${inputFile} not found`);
+            hasErrors = true;
         }
     });
 
+    if (hasErrors) {
+        return false;
+    }
     done();
 });
📝 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
grunt.registerTask('tailwind', function() {
const done = this.async();
// Process each file mapping
Object.entries(tailwindFileMap).forEach(([phpFile, cssFile]) => {
const inputFile = `src/css/${cssFile}`;
const outputFile = `assets/css/${cssFile}`;
// Ensure the input file exists
if (grunt.file.exists(inputFile)) {
// Run the tailwind command
grunt.task.run(`shell:tailwind:${inputFile}:${outputFile}`);
}
});
done();
});
grunt.registerTask('tailwind', function() {
const done = this.async();
let hasErrors = false;
// Process each file mapping
Object.entries(tailwindFileMap).forEach(([phpFile, cssFile]) => {
const inputFile = `src/css/${cssFile}`;
const outputFile = `assets/css/${cssFile}`;
// Ensure the input file exists
if (grunt.file.exists(inputFile)) {
// Run the tailwind command
grunt.task.run(`shell:tailwind:${inputFile}:${outputFile}`);
} else {
grunt.log.error(`Input file ${inputFile} not found`);
hasErrors = true;
}
});
if (hasErrors) {
return false;
}
done();
});

Comment on lines +270 to +274
<a
href="#wpuf-form-builder-notification"
@click="active_tab = 'notification'"
:class="active_tab === 'notification' ? 'wpuf-bg-white wpuf-text-gray-800 wpuf-rounded-md wpuf-drop-shadow-sm' : ''"
class="wpuf-nav-tab wpuf-nav-tab-active wpuf-text-gray-800 wpuf-py-2 wpuf-px-4 wpuf-text-sm hover:wpuf-bg-white hover:wpuf-text-gray-800 hover:wpuf-rounded-md hover:wpuf-drop-shadow-sm focus:wpuf-shadow-none wpuf-mr-2">
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix redundant active class in notification tab

The notification tab has wpuf-nav-tab-active class hardcoded, which conflicts with the dynamic class binding.

-            class="wpuf-nav-tab wpuf-nav-tab-active wpuf-text-gray-800 wpuf-py-2 wpuf-px-4 wpuf-text-sm hover:wpuf-bg-white hover:wpuf-text-gray-800 hover:wpuf-rounded-md hover:wpuf-drop-shadow-sm focus:wpuf-shadow-none wpuf-mr-2">
+            class="wpuf-nav-tab wpuf-text-gray-800 wpuf-py-2 wpuf-px-4 wpuf-text-sm hover:wpuf-bg-white hover:wpuf-text-gray-800 hover:wpuf-rounded-md hover:wpuf-drop-shadow-sm focus:wpuf-shadow-none wpuf-mr-2">
📝 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
<a
href="#wpuf-form-builder-notification"
@click="active_tab = 'notification'"
:class="active_tab === 'notification' ? 'wpuf-bg-white wpuf-text-gray-800 wpuf-rounded-md wpuf-drop-shadow-sm' : ''"
class="wpuf-nav-tab wpuf-nav-tab-active wpuf-text-gray-800 wpuf-py-2 wpuf-px-4 wpuf-text-sm hover:wpuf-bg-white hover:wpuf-text-gray-800 hover:wpuf-rounded-md hover:wpuf-drop-shadow-sm focus:wpuf-shadow-none wpuf-mr-2">
<a
href="#wpuf-form-builder-notification"
@click="active_tab = 'notification'"
:class="active_tab === 'notification' ? 'wpuf-bg-white wpuf-text-gray-800 wpuf-rounded-md wpuf-drop-shadow-sm' : ''"
class="wpuf-nav-tab wpuf-text-gray-800 wpuf-py-2 wpuf-px-4 wpuf-text-sm hover:wpuf-bg-white hover:wpuf-text-gray-800 hover:wpuf-rounded-md hover:wpuf-drop-shadow-sm focus:wpuf-shadow-none wpuf-mr-2">

Comment on lines +32 to +50
/**
* Dequeue assets to avoid conflict
*
* @since WPUF_SINCE
*
* @return void
*/
public function dequeue_assets() {
$post_form_page = 'wpuf-post-forms';

if ( strpos( get_current_screen()->id, $post_form_page ) === false ) {
return;
}

wp_dequeue_style( 'wpuf-form-builder' );
if ( defined( 'WPUF_PRO_VERSION' ) && version_compare( WPUF_PRO_VERSION, '4.1', '<' ) ) {
wp_dequeue_style( 'wpuf-form-builder-pro' );
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Define WPUF_SINCE constant

The @since WPUF_SINCE docblock uses an undefined constant. This should be replaced with the actual version number.

-     * @since WPUF_SINCE
+     * @since 4.0.0
📝 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
/**
* Dequeue assets to avoid conflict
*
* @since WPUF_SINCE
*
* @return void
*/
public function dequeue_assets() {
$post_form_page = 'wpuf-post-forms';
if ( strpos( get_current_screen()->id, $post_form_page ) === false ) {
return;
}
wp_dequeue_style( 'wpuf-form-builder' );
if ( defined( 'WPUF_PRO_VERSION' ) && version_compare( WPUF_PRO_VERSION, '4.1', '<' ) ) {
wp_dequeue_style( 'wpuf-form-builder-pro' );
}
}
/**
* Dequeue assets to avoid conflict
*
* @since 4.0.0
*
* @return void
*/
public function dequeue_assets() {
$post_form_page = 'wpuf-post-forms';
if ( strpos( get_current_screen()->id, $post_form_page ) === false ) {
return;
}
wp_dequeue_style( 'wpuf-form-builder' );
if ( defined( 'WPUF_PRO_VERSION' ) && version_compare( WPUF_PRO_VERSION, '4.1', '<' ) ) {
wp_dequeue_style( 'wpuf-form-builder-pro' );
}
}

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