-
Notifications
You must be signed in to change notification settings - Fork 149
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: post form builder settings #1513
base: develop
Are you sure you want to change the base?
enhance: post form builder settings #1513
Conversation
…or_form_builder_ui_redesign
commit daae343 Author: Sapayth Hossain <sapayth@users.noreply.github.com> Date: Fri Oct 25 10:21:05 2024 +0600 fix logo, minor css commit 7590512 Author: Sapayth Hossain <sapayth@users.noreply.github.com> Date: Thu Oct 17 13:00:12 2024 +0600 pro icon and link commit b720564 Author: Sapayth Hossain <sapayth@users.noreply.github.com> Date: Wed Oct 16 17:31:46 2024 +0600 action buttons commit 743860f Author: Sapayth Hossain <sapayth@users.noreply.github.com> 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 <sapayth@users.noreply.github.com> 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 <sapayth@users.noreply.github.com> Date: Tue Oct 15 17:24:24 2024 +0600 column field, section break commit 63f6663 Author: Sapayth Hossain <sapayth@users.noreply.github.com> Date: Mon Oct 14 21:47:26 2024 +0600 regular fields
…der_stage_form_builder_ui_redesign
…der_stage_form_builder_ui_redesign
…der_stage_form_builder_ui_redesign
…der_stage_form_builder_ui_redesign
WalkthroughThis pull request implements a series of enhancements across the form builder. A new Tailwind CSS task is added in Gruntfile.js while the core client now calls get_plugin_data with extra parameters. Multiple Vue components and mixins are introduced or updated—improving tooltips, data handling, and drag-and-drop features. Styling is overhauled via LESS and CSS with new color variables and dropzone adjustments. The admin UI, templates, AJAX methods, and asset registration have been refined, and numerous form field classes received updated iconography and configuration changes, including removal of a numeric field. Changes
Suggested labels
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 27
🔭 Outside diff range comments (2)
includes/Admin/Forms/Post/Templates/Post_Form_Template_WooCommerce.php (1)
277-284
: 🛠️ Refactor suggestionConsider using WordPress functions instead of direct SQL.
The
update_reviews
method uses direct SQL queries. Consider usingwp_update_post()
(currently commented out) instead for better maintainability and compatibility.public function update_reviews($post_id) { - global $wpdb; $reviews = get_post_meta($post_id, 'product_reviews', true); $status = !empty($reviews) ? 'open' : 'closed'; - $comment_sql = "UPDATE {$wpdb->prefix}posts SET comment_status='{$status}' WHERE ID={$post_id} AND post_status='publish' AND post_type='product'"; - $wpdb->get_results($comment_sql); + wp_update_post([ + 'ID' => $post_id, + 'comment_status' => $status + ]); }includes/Ajax/Admin_Form_Builder_Ajax.php (1)
34-36
:⚠️ Potential issueRemove duplicate authorization check.
The authorization check is duplicated. Remove one of the identical blocks.
Apply this diff to fix the duplication:
- if ( ! current_user_can( wpuf_admin_role() ) ) { - wp_send_json_error( __( 'Unauthorized operation', 'wp-user-frontend' ) ); - }
🧹 Nitpick comments (73)
includes/Fields/Form_Field_SectionBreak.php (1)
92-92
: Document the new divider property.The new 'divider' property would benefit from documentation explaining its purpose and available values (e.g., what other values besides 'regular' are supported?).
Consider adding PHPDoc comments above the
get_field_props()
method to document the new property:/** * Get the field props * + * Properties: + * - divider: string - Controls the section break style ('regular', etc.) * * @return array */admin/form-builder/assets/js/components/form-textarea_field/template.php (1)
5-5
: Remove redundant default value binding.The default value is bound twice: once through the
:default
prop and again as content within the textarea. This is redundant and could lead to inconsistencies.Apply this diff to fix the redundancy:
- :default="field.default" :rows="field.rows" :cols="field.cols" - :class="builder_class_names('textareafield')">{{ field.default }}</textarea> + :class="builder_class_names('textareafield')" + v-model="field.default"></textarea>Also applies to: 8-8
assets/less/frontend-forms.less (1)
2070-2074
: Dropzone Styling Enhanced: Verify Visual Consistency and ResponsivenessThe new
.form-preview-stage-dropzone
rule applies a subtle green background (#f0fdf4
) with a matching border (1px solid #4ade80
) and a fixed height of50px
. This clearly defines the dropzone area for form previews. Please ensure that:
- These color choices are in harmony with the overall design scheme.
- The fixed height works well across different devices and responsive layouts.
- You consider adding hover/focus states to provide additional visual feedback for enhanced usability.
includes/Fields/Form_Field_Column.php (2)
83-83
: LGTM! Help text now accurately describes the field's purpose.The updated help text provides clear guidance about the field's purpose and its maximum limit, which aligns with the
max_column
property defined inget_field_props()
.Consider adding the minimum limit as well for completeness:
- 'help_text' => __( 'How many columns should be there. Maximum 3', 'wp-user-frontend' ), + 'help_text' => __( 'How many columns should be there. Minimum 1, Maximum 3', 'wp-user-frontend' ),
26-59
: Consider enhancing error handling in the render method.The
render
method could benefit from additional error handling for edge cases:
- Validate that
$columns
is within min-max bounds- Ensure
$columns_size
array has all required keys- Validate that
$inner_fields
array is properly structuredConsider adding validation at the start of the render method:
public function render( $field_settings, $form_id, $type = 'post', $post_id = null ) { $columns = isset($field_settings['columns']) ? (int) $field_settings['columns'] : 1; if ($columns < 1 || $columns > 3) { $columns = 1; // fallback to single column } $columns_size = isset($field_settings['inner_columns_size']) ? $field_settings['inner_columns_size'] : []; for ($i = 1; $i <= $columns; $i++) { if (!isset($columns_size["column-$i"])) { $columns_size["column-$i"] = (100 / $columns) . '%'; } } // ... rest of the method }admin/form-builder/assets/js/components/field-visibility/index.js (1)
49-51
: Consider removing empty methods object.The empty methods object can be removed to improve code cleanliness.
- methods: { - - },admin/form-builder/assets/js/components/field-visibility/template.php (4)
15-19
: Add ARIA labels for better accessibility.The radio inputs lack proper ARIA labels which are important for screen readers.
<input type="radio" :value="key" v-model="selected" + :aria-label="option" class="checked:!wpuf-bg-primary checked:before:!wpuf-bg-transparent">
31-36
: Maintain consistent class usage across inputs.The radio input in the inline section uses
builder_class_names('radio')
while the non-inline section uses hardcoded classes. Consider using the builder class names consistently.<input type="radio" :value="key" v-model="selected" - class="checked:!wpuf-bg-primary checked:before:!wpuf-bg-transparent"> + :class="builder_class_names('radio')">
45-57
: Consider moving PHP logic to a separate component.The PHP logic for generating roles and subscription checkboxes could be moved to a separate Vue component or computed property for better maintainability and separation of concerns.
Example approach:
- Create a new component for role/subscription options
- Move the PHP logic to the backend API
- Fetch the data through the component's lifecycle hooks
- Render using v-for directive
This would make the template more maintainable and consistent with Vue.js best practices.
Also applies to: 62-82
50-52
: Standardize checkbox styling across roles and subscriptions.The checkbox styling is inconsistent between roles and subscriptions sections.
- $output .= "<label><input :class=\"builder_class_names('checkbox')\" type=\"checkbox\" v-model=\"choices\" value=\"{$role}\"> {$role_name} </label>"; + $output .= "<label><input class='wpuf-bg-transparent wpuf-shadow-primary' type=\"checkbox\" v-model=\"choices\" value=\"{$role}\"> {$role_name} </label>";Or preferably, use the builder class names for both:
- $output .= "<label><input class='wpuf-bg-transparent wpuf-shadow-primary' type='checkbox' v-model='choices' value='{$pack->ID}' > {$pack->post_title} </label>"; + $output .= "<label><input :class=\"builder_class_names('checkbox')\" type='checkbox' v-model='choices' value='{$pack->ID}' > {$pack->post_title} </label>";Also applies to: 70-72
admin/form-builder/assets/js/components/form-column_field/index.js (1)
139-139
: Remove unused methodis_pro_feature
.The method
is_pro_feature
appears to be unused since its functionality has been replaced byis_pro_preview
. Consider removing it to maintain code cleanliness.- is_pro_feature: function (template) { - return (this.field_settings[template] && this.field_settings[template].pro_feature) ? true : false; - },Also applies to: 154-156
admin/form-builder/assets/js/components/field-option-data/template.php (3)
7-22
: Minor: Add space after the closing tag.In line 20, add a space between the closing tag and the text for consistent formatting:
- /><?php esc_attr_e( 'Sync values', 'wp-user-frontend' ); ?> + /> <?php esc_attr_e( 'Sync values', 'wp-user-frontend' ); ?>
24-126
: Enhance accessibility for interactive elements.Add appropriate ARIA labels to improve accessibility:
- <i class="fa fa-bars sort-handler hover:!wpuf-cursor-move wpuf-text-gray-400"></i> + <i class="fa fa-bars sort-handler hover:!wpuf-cursor-move wpuf-text-gray-400" aria-label="<?php esc_attr_e( 'Drag to reorder', 'wp-user-frontend' ); ?>"></i> - disabled + disabled + aria-label="<?php esc_attr_e( 'Label column header', 'wp-user-frontend' ); ?>" - class="action-buttons hover:wpuf-cursor-pointer"> + class="action-buttons hover:wpuf-cursor-pointer" + aria-label="<?php esc_attr_e( 'Delete option', 'wp-user-frontend' ); ?>"> - class="plus-buttons hover:wpuf-cursor-pointer !wpuf-border-0"> + class="plus-buttons hover:wpuf-cursor-pointer !wpuf-border-0" + aria-label="<?php esc_attr_e( 'Add new option', 'wp-user-frontend' ); ?>">
128-134
: Add keyboard focus styles for better accessibility.The clear selection link should have visible focus styles for keyboard navigation:
class="wpuf-inline-flex wpuf-items-center wpuf-gap-x-2 wpuf-rounded-md wpuf-px-3 wpuf-py-2 wpuf-text-sm wpuf-text-gray-700 hover:wpuf-text-gray-700 hover:wpuf-bg-gray-50 wpuf-ring-1 wpuf-ring-inset wpuf-ring-gray-300 wpuf-mt-4" + class="wpuf-inline-flex wpuf-items-center wpuf-gap-x-2 wpuf-rounded-md wpuf-px-3 wpuf-py-2 wpuf-text-sm wpuf-text-gray-700 hover:wpuf-text-gray-700 hover:wpuf-bg-gray-50 wpuf-ring-1 wpuf-ring-inset wpuf-ring-gray-300 wpuf-mt-4 focus:wpuf-outline-none focus:wpuf-ring-2 focus:wpuf-ring-primary"
includes/Admin/Forms/Post/Templates/Post_Form_Template_Post.php (1)
34-36
: Good enhancement of form field properties.The addition of width and restriction properties improves form field configuration and constraints. However, consider extracting these common configurations into a shared configuration object to maintain DRY principles.
private $defaultTextFieldConfig = [ 'width' => 'large', 'restriction_to' => 'max', 'restriction_type' => 'character' ];Also applies to: 78-79, 116-117
admin/form-builder/assets/js/components/help-text/template.php (2)
1-5
: Enhance accessibility of the tooltip element.While the HTML structure is semantically correct, consider adding ARIA attributes to improve accessibility:
<span class="field-helper-text wpuf-ml-2" :data-placement="placement" data-toggle="tooltip" - data-container="body"> + data-container="body" + role="tooltip" + aria-label="{{ text }}">
6-9
: Add accessibility attributes to the SVG icon.The SVG implementation looks clean, but needs accessibility improvements:
-<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none"> +<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" + role="img" + aria-hidden="true" + focusable="false">includes/Admin/Menu.php (2)
124-127
: Consider improving the email subject for better tracking.The footer help message includes a generic email subject. Consider making it more specific for better tracking and organization of integration requests.
- 'mailto:support@wedevs.com?subject=WPUF Custom Post Template Integration Request' + 'mailto:support@wedevs.com?subject=[WPUF][Integration Request] New Post Template'
133-133
: Verify the modal template path.The code includes a modal template using a hardcoded path. Consider using WordPress path constants or functions for better maintainability.
- require_once WPUF_ROOT . '/includes/Admin/template-parts/modal-v4.1.php'; + require_once WPUF_INCLUDES . '/Admin/template-parts/modal-v4.1.php';includes/Fields/Form_Field_Featured_Image.php (1)
98-98
: Good security practices, consider additional validation.The code demonstrates good security practices:
- Nonce verification for form submission
- POST data sanitization
- Proper HTML escaping
- File type restrictions to images
Consider adding:
- Server-side validation of uploaded file MIME types
- Additional checks for malicious image files (e.g., PHP code in EXIF data)
// Add this validation in prepare_entry method $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($finfo, $file_path); $allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp']; if (!in_array($mime_type, $allowed_types)) { wp_die('Invalid file type'); }Also applies to: 169-169
includes/Admin/Forms/Admin_Form.php (1)
254-277
: Consider accessibility and expand/collapse states.This new UI block uses Tailwind classes for spacing, flex layout, and an angle-down icon to convey a collapsible "Post Settings" panel. Please ensure there's an accessible toggle mechanism (e.g., keyboard navigation, ARIA attributes) for users who rely on assistive technologies.
Would you like assistance in adding ARIA attributes or a keyboard handler to improve accessibility?
admin/form-builder/assets/js/form-builder.js (8)
73-76
: Resettingediting_field_id
across panels.The logic here ensures that navigating to either
'form-fields'
or'form-fields-v4-1'
resetsediting_field_id
. Verify that you do not lose needed context unexpectedly (e.g., partial field edits) when switching panels.
93-96
: Check for possible empty array access.In
open_field_settings
,field[0]
is accessed without validatingfield.length > 0
. Although you filter before, a second check or guard is safer if upstream code changes behavior.+ if (!field.length) { + return; + }Also applies to: 106-108
244-244
: Panel assignment when deleting a field.Here you revert back to
'form-fields'
or'form-fields-v4-1'
after a field is deleted, but no check is made if the user is in'field-options'
. Confirm that it doesn't disrupt any more advanced usage scenario or misalign the UI for registration forms.
395-403
: Load default panel sections outside of store.
set_panel_sections
andset_default_panel_sections
conveniently revert or override panel sections. Consider a pre-initialization step: dispatching an action or reading from a config object for more flexibility and testability.
505-511
: Proper placement ofnextTick
calls.Invoking
Vue.nextTick
ensures that DOM updates are applied before running selectize. Revisit if we can run selectize after mount or inside a custom directive for more robust plugin initialization. OverusingnextTick
can make sequence flows harder to trace.
641-643
: Avoid direct store manipulation.When checking
if (panel === 'form-fields-v4-1') this.$store.state.panel_sections = ...
, updating store state directly outside of a mutation can be error-prone. Consider exposing a mutation (e.g.,updatePanelSections
) or an action for reactivity best practices.
708-725
: Customizable field styling.
setting_class_names
returns multiple Tailwind utility classes for each field type. If future field types are added, remember to extend this method. Alternatively, centralize style definitions in a config for easier reuse or theming.
727-734
: Modularize tab transitions.
switch_settings_menu
setsactive_settings_tab
andactive_settings_title
. If additional logic (e.g., analytics, user permission checks) is needed, you can place them here or in a dedicated function for better maintainability.assets/js/wpuf-form-builder.js (3)
636-636
: Apply the NOT operator rather than a Boolean ternary.As with the previous file, replace:
-this.is_form_switcher = (this.is_form_switcher) ? false : true; +this.is_form_switcher = !this.is_form_switcher;🧰 Tools
🪛 Biome (1.9.4)
[error] 636-636: 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)
708-725
: Centralize style definitions.
setting_class_names
returns multiple utility classes for each field type. If your plugin expands with more field types or design themes, consider moving this logic to a dedicated config or a small plugin-based style system for consistency and easier updates.
727-734
: Consider grouping settings logic.
switch_settings_menu
modifiesactive_settings_tab
andactive_settings_title
. Future expansions (like storing user preferences or adding analytics) might benefit from one consolidated method.assets/js/wpuf-form-builder-components.js (5)
267-315
: [Refactor Suggestion] Eliminate redundantvar self = this
Inside arrow functions,this
is already preserved from the enclosing context. You can safely removevar self = this
and invokethis.$store.commit
directly.Apply the following diff to remove the alias:
- delete_field: function(index) { - var self = this; + delete_field: function(index) { (Swal.fire({ text: this.i18n.delete_field_warn_msg, ... })).then((result) => { - if (result.isConfirmed) { self.$store.commit('delete_form_field_element', index); } + if (result.isConfirmed) { this.$store.commit('delete_form_field_element', index); } }); }🧰 Tools
🪛 Biome (1.9.4)
[error] 297-297: 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)
327-329
: [Refactor Suggestion] Simplify boolean return
Avoid using a ternary that returns explicittrue : false
and directly return the boolean expression.Here’s a concise alternative:
-return ( this.field_settings[template] && this.field_settings[template].pro_feature ) ? true : false; +return !!(this.field_settings[template] && this.field_settings[template].pro_feature);🧰 Tools
🪛 Biome (1.9.4)
[error] 328-328: 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] 328-328: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
350-355
: [Refactor Suggestion] Consider optional chaining
You can simplify this check by using optional chaining and returning a direct boolean.Example:
- if (this.field_settings[template] && this.field_settings[template].is_full_width) { - return true; - } - return false; + return !!this.field_settings[template]?.is_full_width;🧰 Tools
🪛 Biome (1.9.4)
[error] 351-351: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
359-359
: [Refactor Suggestion] Remove noUselessTernary
Same pattern as above. The conditional returns a boolean directly.-return ( field.recaptcha_type && 'invisible_recaptcha' === field.recaptcha_type ) ? true : false; +return field.recaptcha_type && (field.recaptcha_type === 'invisible_recaptcha');🧰 Tools
🪛 Biome (1.9.4)
[error] 359-359: 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)
1114-1117
: [Nitpick] Separated action button classes
Returning a static set of Tailwind classes is fine, but consider grouping them into one shared object or using computed inline style for more flexibility.assets/js-templates/form-components.php (1)
93-205
: [Refactor Suggestion] Evaluate deeper Vue transitions
While the markup is well-structured with classes, consider advanced Vue transitions for the added and removed fields to improve user experience.admin/form-builder/assets/js/components/form-email_address/template.php (1)
4-4
: Standardize class binding approach.The concatenation of
class_names('email')
andbuilder_class_names('text')
is inconsistent with other form field components. Consider standardizing this approach.- :class="class_names('email') + builder_class_names('text')" + :class="builder_class_names('email')"admin/form-builder/assets/js/components/form-recaptcha/template.php (1)
7-7
: LGTM! Consider enhancing image accessibility.The strict comparison operator is a good improvement. Consider adding a more descriptive alt text for better accessibility.
- <img v-if="'invisible_recaptcha' !== field.recaptcha_type" class="wpuf-recaptcha-placeholder" src="<?php echo WPUF_ASSET_URI . '/images/recaptcha-placeholder.png'; ?>" alt=""> + <img v-if="'invisible_recaptcha' !== field.recaptcha_type" class="wpuf-recaptcha-placeholder" src="<?php echo WPUF_ASSET_URI . '/images/recaptcha-placeholder.png'; ?>" alt="reCAPTCHA verification widget">admin/form-builder/assets/js/components/field-option-pro-feature-alert/template.php (1)
1-6
: LGTM! Consider enhancing tooltip accessibility.The styling improvements and WordPress i18n usage look good. Consider adding ARIA attributes for better accessibility of the tooltip.
<label - class="wpuf-pro-text-alert wpuf-ml-2 wpuf-tooltip-top" + class="wpuf-pro-text-alert wpuf-ml-2 wpuf-tooltip-top" + role="tooltip" + aria-label="<?php esc_attr_e( 'Available in PRO version', 'wp-user-frontend' ); ?>" data-tip="<?php esc_attr_e( 'Available in PRO version', 'wp-user-frontend' ); ?>">admin/form-builder/assets/js/components/form-dropdown_field/template.php (2)
2-11
: LGTM! Consider enhancing select accessibility.The class binding and semantic changes look good. Consider adding ARIA attributes for better accessibility.
<select - :class="builder_class_names('dropdown')"> + :class="builder_class_names('dropdown')" + :aria-label="field.label" + :aria-describedby="field.help ? field.name + '_help' : null">
12-12
: LGTM! Consider adding ID for ARIA description.The help text semantic change improves accessibility. Consider adding an ID for ARIA description reference.
- <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-post_title/template.php (2)
7-8
: Consider consolidating class bindings.Having both dynamic and static classes might lead to conflicts. Consider consolidating them into a single binding.
- :class="class_names('textfield')" - class="wpuf-block wpuf-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300" + :class="[ + class_names('textfield'), + 'wpuf-block wpuf-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300' + ]"
10-10
: LGTM! Consider adding ID for ARIA description.The help text semantic change improves accessibility. Consider adding an ID for ARIA description reference.
- <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-post_content/template.php (1)
16-23
: Consider adding character limit validation.For the textarea field, consider adding character limit validation to prevent excessively long content.
Apply this diff to add character limit:
<textarea v-if="'no' === field.rich" :class="builder_class_names('textareafield')" :placeholder="field.placeholder" :default_text="field.default" :rows="field.rows" :cols="field.cols" + :maxlength="field.max_length" >{{ field.default }}</textarea>
admin/form-builder/assets/js/components/form-image_upload/template.php (1)
4-19
: Verify the use of different SVG icons.While the styling improvements are good, the SVG icon used here differs from the featured image component. Consider using consistent icons for similar actions.
For consistency, consider using the same icon as the featured image component:
- <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> + <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"> + <path stroke-linecap="round" stroke-linejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" /> + </svg>admin/form-builder/assets/js/mixins/option-field.js (2)
7-10
: Consider using a more meaningful default value.The default value
{ key: 'value' }
seems generic. Consider using a more meaningful default value that better represents the expected structure of an option field.- default: () => ({ key: 'value' }) + default: () => ({ + type: 'text', + label: '', + value: '' + })
12-15
: Consider using a more meaningful default value.Similarly, the default value for
editing_form_field
should better represent the expected structure of a form field being edited.- default: () => ({ key: 'value' }) + default: () => ({ + id: '', + type: 'text', + settings: {} + })admin/form-builder/assets/js/mixins/global.js (2)
10-12
: Consider using strict comparison and boolean conversion.The
is_pro_active
computed property could be more robust with strict comparison and explicit boolean conversion.- return wpuf_form_builder.is_pro_active === '1'; + return Boolean(wpuf_form_builder.is_pro_active === '1');
14-16
: Consider adding null check for pro_link.The
pro_link
computed property should handle cases where the configuration might be undefined.- return wpuf_form_builder.pro_link; + return wpuf_form_builder.pro_link || '';admin/form-builder/assets/js/components/builder-stage-v4-1/index.js (2)
141-142
: Simplify boolean expressions.The ternary expressions returning boolean literals can be simplified:
- return ( this.field_settings[template] && this.field_settings[template].pro_feature ) ? true : false; + return !!(this.field_settings[template]?.pro_feature); - return ( field.recaptcha_type && 'invisible_recaptcha' === field.recaptcha_type ) ? true : false; + return field.recaptcha_type === 'invisible_recaptcha';Also applies to: 172-173
🧰 Tools
🪛 Biome (1.9.4)
[error] 141-141: 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] 141-141: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
110-128
: Remove unnecessary this aliasing in arrow function.Arrow functions inherit
this
from their enclosing scope, making theself
variable unnecessary.- var self = this; - (Swal.fire({ - text: self.i18n.delete_field_warn_msg, + text: this.i18n.delete_field_warn_msg, icon: 'warning', showCancelButton: true, confirmButtonColor: '#d54e21', - confirmButtonText: self.i18n.yes_delete_it, - cancelButtonText: self.i18n.no_cancel_it, + confirmButtonText: this.i18n.yes_delete_it, + cancelButtonText: this.i18n.no_cancel_it, customClass: { confirmButton: 'btn btn-success', cancelButton: 'btn btn-danger', } })).then((result) => { if (result.isConfirmed) { - self.$store.commit('delete_form_field_element', index); + this.$store.commit('delete_form_field_element', index); } });🧰 Tools
🪛 Biome (1.9.4)
[error] 110-110: This aliasing of this is unnecessary.
Arrow functions inherits
this
from their enclosing scope.
Safe fix: Use this instead of an alias.(lint/complexity/noUselessThisAlias)
admin/form-builder/assets/js/components/form-column_field/template.php (2)
1-3
: Consider using semantic HTML elements for better accessibility.The outer container uses multiple utility classes for styling. Consider using semantic HTML elements like
<section>
or<article>
to improve accessibility.-<div +<section :class="'has-columns-'+field.columns" class="wpuf-field-columns wpuf-flex wpuf-flex-col md:wpuf-flex-row wpuf-gap-4 wpuf-p-4 wpuf-w-full">
19-27
: Improve class readability by extracting complex class bindings.The class binding logic is complex and could be moved to a computed property for better maintainability.
Consider creating a computed property:
computed: { getFieldClasses() { return [ 'wpuf-m-0', 'wpuf-p-0', 'wpuf-group/column-inner', 'hover:wpuf-bg-green-50', 'wpuf-transition', 'wpuf-duration-150', 'wpuf-ease-out', 'column-field-items', 'wpuf-el', 'wpuf-rounded-t-md', this.field.name, this.field.css, 'form-field-' + this.field.template, this.field.width ? 'field-size-' + this.field.width : '', ('custom_hidden_field' === this.field.template) ? 'hidden-field' : '', parseInt(this.editing_form_id) === parseInt(this.field.id) ? 'wpuf-bg-green-50' : '' ] } }Then use it in the template:
-:class="[ - field.name, - field.css, - 'form-field-' + field.template, - field.width ? 'field-size-' + field.width : '', - ('custom_hidden_field' === field.template) ? 'hidden-field' : '', - parseInt(editing_form_id) === parseInt(field.id) ? 'wpuf-bg-green-50' : '' -]" +:class="getFieldClasses"admin/form-builder/assets/js/components/form-fields-v4-1/index.js (2)
7-7
: Consider using named imports for better code organization.The mixins are concatenated using a function call. Consider using named imports for better code organization and type checking.
-mixins: wpuf_form_builder_mixins(wpuf_mixins.form_fields).concat(wpuf_mixins.add_form_field), +import { formFieldsMixin, addFormFieldMixin } from './mixins'; + +mixins: [formFieldsMixin, addFormFieldMixin],
33-49
: Improve jQuery UI draggable initialization.The draggable initialization code could be moved to a separate method for better maintainability and reusability.
+methods: { + initDraggable(buttons) { + buttons.each(function() { + if ($(this).draggable('instance')) { + $(this).draggable('destroy'); + } + }); + + buttons.draggable({ + connectToSortable: '#form-preview-stage, #form-preview-stage .wpuf-form, .wpuf-column-inner-fields .wpuf-column-fields-sortable-list', + helper: 'clone', + revert: 'invalid', + cancel: '.button-faded', + }).disableSelection(); + } +}, mounted: function() { var self = this; Vue.nextTick(function() { var buttons = $(self.$el).find('.panel-form-field-buttons .wpuf-field-button'); - buttons.each(function() { - if ($(this).draggable('instance')) { - $(this).draggable('destroy'); - } - }); - - buttons.draggable({ - connectToSortable: '#form-preview-stage, #form-preview-stage .wpuf-form, .wpuf-column-inner-fields .wpuf-column-fields-sortable-list', - helper: 'clone', - revert: 'invalid', - cancel: '.button-faded', - }).disableSelection(); + self.initDraggable(buttons); }); }includes/Admin/template-parts/modal-v4.1.php (1)
135-173
: Improve JavaScript event handling.The JavaScript code could be improved by using event delegation and modern JavaScript features.
<script type="text/javascript"> -( function ( $ ) { +( function ( $ ) { var popup = { + selectors: { + addFormButton: 'a.page-title-action.add-form', + closeButton: '.wpuf-form-template-modal .wpuf-close-btn', + modal: '.wpuf-form-template-modal', + wrap: '#wpbody-content .wrap' + }, + 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 ) ); + $( document ) + .on( 'click', this.selectors.addFormButton, this.openModal.bind(this) ) + .on( 'click', this.selectors.closeButton, this.closeModal.bind(this) ); - $( 'body' ).on( 'keydown', $.proxy( this.onEscapeKey, this ) ); + $( document ).on( 'keydown', this.onEscapeKey.bind(this) ); }, openModal: function ( e ) { e.preventDefault(); - $( '.wpuf-form-template-modal' ).show(); - $( '#wpbody-content .wrap' ).hide(); + $( this.selectors.modal ).show(); + $( this.selectors.wrap ).hide(); }, onEscapeKey: function ( e ) { - if (27 === e.keyCode) { + if ( e.key === 'Escape' ) { this.closeModal( e ); } }, closeModal: function ( e ) { - if (typeof e !== 'undefined') { + if ( e ) { e.preventDefault(); } - $( '.wpuf-form-template-modal' ).hide(); - $( '#wpbody-content .wrap' ).show(); + $( this.selectors.modal ).hide(); + $( this.selectors.wrap ).show(); } }; $( function () { popup.init(); } ); } )( jQuery ); </script>Gruntfile.js (2)
3-6
: Consider using a more flexible file mapping configuration.The file mapping is hardcoded. Consider moving it to a separate configuration file for better maintainability.
+// tailwind.config.json +{ + "fileMap": { + "admin/form-builder/views/form-builder-v4.1.php": "admin/form-builder.css", + "admin/form-builder/views/settings-sidebar.php": "admin/form-builder.css" + } +} -const tailwindFileMap = { - 'admin/form-builder/views/form-builder-v4.1.php': 'admin/form-builder.css', - 'admin/form-builder/views/settings-sidebar.php': 'admin/form-builder.css', -} +const tailwindConfig = require('./tailwind.config.json'); +const tailwindFileMap = tailwindConfig.fileMap;
122-135
: Optimize watch task configuration.The watch task could be optimized by using more specific file patterns and adding error handling.
tailwind: { files: [ - 'src/css/**/*.css', - 'admin/form-builder/views/*.php', - 'admin/form-builder/assets/js/**/*.php', - 'admin/form-builder/assets/js/**/*.js', - 'includes/Admin/**/*.php', - 'wpuf-functions.php', + 'src/css/admin/**/*.css', + 'admin/form-builder/**/*.{php,js}', + 'includes/Admin/**/*.php' ], - tasks: ['shell:tailwind:src/css/admin/form-builder.css:assets/css/admin/form-builder.css'], + tasks: ['tailwind'], options: { - spawn: false + spawn: false, + event: ['added', 'changed'], + atBegin: true } },assets/js/wpuf-form-builder-mixins.js (3)
24-33
: Improve error notification configuration.The error notification configuration is hardcoded. Consider extracting it to a separate configuration object for better maintainability.
Apply this refactor:
+const ERROR_NOTIFICATION_CONFIG = { + title: '<span class="wpuf-text-orange-400">Oops...</span>', + html: '<p class="wpuf-text-gray-500 wpuf-text-xl wpuf-m-0 wpuf-p-0">You already have this field in the form</p>', + imageUrl: wpuf_form_builder.asset_url + '/images/oops.svg', + showCloseButton: true, + padding: '1rem', + width: '35rem', + customClass: { + confirmButton: "!wpuf-flex focus:!wpuf-shadow-none !wpuf-bg-primary", + closeButton: "wpuf-absolute" + } +}; -Swal.fire({ - title: '<span class="wpuf-text-orange-400">Oops...</span>', - // ... other properties -}); +Swal.fire(ERROR_NOTIFICATION_CONFIG);
60-64
: Add documentation for pro feature detection.The
is_pro_preview
method lacks documentation explaining its purpose and usage.Add JSDoc documentation:
+/** + * Checks if a template is a pro feature and if pro version is not active + * @param {string} template - The template name to check + * @returns {boolean} - True if template is pro feature and pro version is not active + */ is_pro_preview: function (template) { var is_pro_active = wpuf_form_builder.is_pro_active === '1'; return (!is_pro_active && this.field_settings[template] && this.field_settings[template].pro_feature); },
109-139
: Optimize builder class names method.The
builder_class_names
method uses a switch statement for class assignment. Consider using a lookup object for better performance and maintainability.Apply this refactor:
+const CLASS_MAPPINGS = { + upload_btn: 'file-selector wpuf-rounded-md wpuf-btn-secondary', + radio: '!wpuf-mt-0 wpuf-block wpuf-text-sm wpuf-font-medium wpuf-leading-6 wpuf-text-gray-900 checked:focus:!wpuf-bg-primary checked:hover:!wpuf-bg-primary checked:before:!wpuf-bg-white checked:!wpuf-bg-primary', + checkbox: 'wpuf-h-4 wpuf-w-4 wpuf-rounded wpuf-border-gray-300 !wpuf-mt-0.5 checked:focus:!wpuf-bg-primary checked:hover:wpuf-bg-primary checked:!wpuf-bg-primary before:!wpuf-content-none', + dropdown: 'wpuf-block wpuf-w-full wpuf-min-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300', + default: 'wpuf-block wpuf-min-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full' +}; builder_class_names: function(type_class) { - var commonClasses = ''; - switch (type_class) { - case 'upload_btn': - commonClasses = 'file-selector wpuf-rounded-md wpuf-btn-secondary'; - break; - // ... other cases - } + var commonClasses = CLASS_MAPPINGS[type_class] || CLASS_MAPPINGS.default; return [ type_class, this.required_class(), 'wpuf_' + this.field.name + '_' + this.form_id, commonClasses ]; },admin/form-builder/views/form-builder-v4.1.php (1)
63-86
: Improve shortcode copy functionality.The shortcode copy functionality needs better user feedback and accessibility.
Add a toast notification for copy feedback and improve accessibility:
<span class="form-id wpuf-group wpuf-flex wpuf-items-center wpuf-px-4 wpuf-py-3 wpuf-rounded-md wpuf-border wpuf-border-gray-300 hover:wpuf-cursor-pointer wpuf-ml-6 wpuf-text-gray-700 wpuf-text-base wpuf-leading-none" title="<?php printf( esc_html( __( 'Click to copy shortcode', 'wp-user-frontend' ) ) ); ?>" + role="button" + tabindex="0" + @keydown.enter="copyShortcode" + @keydown.space="copyShortcode" data-clipboard-text="<?php printf( esc_attr( '[' . $shortcodes[0]['name'] . ' id="' . esc_attr( $form_id ) . '"]' ) ); ?>">#{{ post.ID }}includes/Admin/Forms/Admin_Form_Builder.php (1)
380-409
: Enhance error handling in get_pro_field_messages method.The method handles HTTP errors but could benefit from more specific error handling.
Consider adding specific error handling for different HTTP status codes:
if ( is_wp_error( $response ) || ( 200 !== $response['response']['code'] ) ) { - return []; + if ( is_wp_error( $response ) ) { + error_log( sprintf( 'WPUF Pro Field Assets Error: %s', $response->get_error_message() ) ); + } else { + error_log( sprintf( 'WPUF Pro Field Assets HTTP Error: %d', $response['response']['code'] ) ); + } + return []; }includes/Admin/Posting.php (1)
61-65
: Consider consolidating style enqueuing.The style enqueuing could be more efficient.
Consider combining the style enqueuing:
-wp_enqueue_style( 'wpuf-admin-form-builder' ); -wp_enqueue_style( 'jquery-ui' ); +$styles = ['wpuf-admin-form-builder', 'jquery-ui']; +foreach ($styles as $style) { + wp_enqueue_style($style); +}admin/form-builder/views/settings-sidebar.php (2)
379-391
: Enhance select field value handling.The select field value handling could be more robust.
Consider adding type checking and sanitization:
-$value_str = is_array($value) ? implode(',', $value) : $value; +$value_str = ''; +if (is_array($value)) { + array_walk($value, 'sanitize_text_field'); + $value_str = implode(',', $value); +} else { + $value_str = sanitize_text_field($value); +}
406-408
: Add PHPCS ignore explanation.The PHPCS ignore directive should be documented.
Add a comment explaining why the PHPCS rule is ignored:
-// phpcs:ignore WordPress.PHP +// phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict -- Loose comparison intended for legacy compatibility $selected = in_array($index, $value) ? 'selected' : '';assets/css/frontend-forms.css (1)
1789-1793
: New Dropzone Styles Added
The addition of the.form-preview-stage-dropzone
class looks well defined, using a light green background (#f0fdf4
), a clear green border (1px solid #4ade80
), and a fixed height of 50px, which aligns with the intended dropzone functionality.
Consider the following enhancements for improved user experience and consistency:
- Interactive Feedback: Adding a hover or active state (for example, changing the border color or background slightly) can enhance the drag-and-drop interaction feedback.
- Responsive Adjustments: If the content inside the dropzone might vary, consider using
min-height
or additional padding instead of a fixed height to ensure good responsiveness.- Tailwind CSS Consistency: Given recent Tailwind CSS workflow integrations, it may be beneficial to leverage shared color variables or utility classes for consistency across the design if applicable.
assets/vendor/selectize/js/standalone/selectize.js (4)
1206-1206
: Avoid Using thedelete
Operator
At this location, the code uses thedelete
operator (e.g. inMicroEvent.prototype.off
) to remove properties from the events object. Thedelete
operator can have performance implications in JavaScript. Consider assigningundefined
instead if this change is compatible with the existing behavior.🧰 Tools
🪛 Biome (1.9.4)
[error] 1206-1206: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
1410-1411
: Consider Refactoring Deletion in Event Removal
Similar to line 1206, the use of thedelete
operator here may negatively affect performance. If feasible, assigningundefined
(or using alternative patterns) might be preferable; however, given that this is vendor code, confirm that any change will not break expected behavior.🧰 Tools
🪛 Biome (1.9.4)
[error] 1410-1411: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
1734-1734
: Modernize Property Checks UsingObject.hasOwn
Multiple parts of the code directly invokehasOwnProperty
on objects (e.g. at these line ranges). It is recommended to useObject.hasOwn()
for more robust property checking. Adjustments here can help avoid potential pitfalls with objects that might have shadowed or missing prototype properties.Also applies to: 2246-2246, 2402-2402, 3446-3446
🧰 Tools
🪛 Biome (1.9.4)
[error] 1734-1734: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
2014-2014
: Unnecessary Aliasing ofthis
Static analysis tools have flagged several instances where a local alias—typically assigned toself
—is created even though arrow functions and modern scoping would allow usingthis
directly. For example, the aliases around these line ranges could potentially be eliminated to simplify the code. Be cautious, however, as the vendor code may retain these patterns for compatibility reasons.Also applies to: 2053-2054, 2599-2599, 2659-2659, 2790-2790, 2828-2828, 2880-2880, 2896-2896, 3167-3167, 3269-3269
🧰 Tools
🪛 Biome (1.9.4)
[error] 2014-2014: 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)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (57)
assets/images/adjustments-horizontal.svg
is excluded by!**/*.svg
assets/images/arrow-up-tray.svg
is excluded by!**/*.svg
assets/images/badge-check.svg
is excluded by!**/*.svg
assets/images/check-circle.svg
is excluded by!**/*.svg
assets/images/checked-green.svg
is excluded by!**/*.svg
assets/images/chevron-down.svg
is excluded by!**/*.svg
assets/images/clock.svg
is excluded by!**/*.svg
assets/images/cloud.svg
is excluded by!**/*.svg
assets/images/code-bracket-square.svg
is excluded by!**/*.svg
assets/images/code.svg
is excluded by!**/*.svg
assets/images/cog-8-tooth.svg
is excluded by!**/*.svg
assets/images/command-line.svg
is excluded by!**/*.svg
assets/images/crown-white.svg
is excluded by!**/*.svg
assets/images/document-check.svg
is excluded by!**/*.svg
assets/images/exclamation-circle.svg
is excluded by!**/*.svg
assets/images/eye-off.svg
is excluded by!**/*.svg
assets/images/form-blank-state.svg
is excluded by!**/*.svg
assets/images/forms/layout1.png
is excluded by!**/*.png
assets/images/forms/layout2.png
is excluded by!**/*.png
assets/images/forms/layout3.png
is excluded by!**/*.png
assets/images/forms/layout4.png
is excluded by!**/*.png
assets/images/forms/layout5.png
is excluded by!**/*.png
assets/images/globe-alt.svg
is excluded by!**/*.svg
assets/images/key-rounded.svg
is excluded by!**/*.svg
assets/images/link.svg
is excluded by!**/*.svg
assets/images/location-marker.svg
is excluded by!**/*.svg
assets/images/lock-icon-rounded-bg.svg
is excluded by!**/*.svg
assets/images/mail.svg
is excluded by!**/*.svg
assets/images/map.svg
is excluded by!**/*.svg
assets/images/menu-alt-2.svg
is excluded by!**/*.svg
assets/images/menu-alt-4.svg
is excluded by!**/*.svg
assets/images/minus-circle-green.svg
is excluded by!**/*.svg
assets/images/oops.svg
is excluded by!**/*.svg
assets/images/photograph.svg
is excluded by!**/*.svg
assets/images/play.svg
is excluded by!**/*.svg
assets/images/plus-circle-green.svg
is excluded by!**/*.svg
assets/images/pro-badge.svg
is excluded by!**/*.svg
assets/images/qrcode.svg
is excluded by!**/*.svg
assets/images/queue-list.svg
is excluded by!**/*.svg
assets/images/recaptcha-placeholder.png
is excluded by!**/*.png
assets/images/rectangle-stack.svg
is excluded by!**/*.svg
assets/images/squares-2x2.svg
is excluded by!**/*.svg
assets/images/squares-2x2.zip
is excluded by!**/*.zip
assets/images/star.svg
is excluded by!**/*.svg
assets/images/stop.svg
is excluded by!**/*.svg
assets/images/tag.svg
is excluded by!**/*.svg
assets/images/templates/blank.svg
is excluded by!**/*.svg
assets/images/templates/edd.png
is excluded by!**/*.png
assets/images/templates/edd.svg
is excluded by!**/*.svg
assets/images/templates/event.svg
is excluded by!**/*.svg
assets/images/templates/post.png
is excluded by!**/*.png
assets/images/templates/post.svg
is excluded by!**/*.svg
assets/images/templates/woocommerce.png
is excluded by!**/*.png
assets/images/templates/woocommerce.svg
is excluded by!**/*.svg
assets/images/title.svg
is excluded by!**/*.svg
assets/images/view-columns.svg
is excluded by!**/*.svg
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (107)
Gruntfile.js
(5 hunks)Lib/Appsero/Client.php
(1 hunks)admin/form-builder/assets/js/components/builder-stage-v4-1/index.js
(1 hunks)admin/form-builder/assets/js/components/builder-stage-v4-1/template.php
(1 hunks)admin/form-builder/assets/js/components/builder-stage/index.js
(1 hunks)admin/form-builder/assets/js/components/field-checkbox/index.js
(1 hunks)admin/form-builder/assets/js/components/field-checkbox/template.php
(1 hunks)admin/form-builder/assets/js/components/field-multiselect/template.php
(1 hunks)admin/form-builder/assets/js/components/field-option-data/index.js
(1 hunks)admin/form-builder/assets/js/components/field-option-data/template.php
(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/index.js
(1 hunks)admin/form-builder/assets/js/components/field-radio/template.php
(1 hunks)admin/form-builder/assets/js/components/field-range/template.php
(1 hunks)admin/form-builder/assets/js/components/field-select/index.js
(2 hunks)admin/form-builder/assets/js/components/field-select/template.php
(1 hunks)admin/form-builder/assets/js/components/field-text-meta/template.php
(1 hunks)admin/form-builder/assets/js/components/field-text/index.js
(1 hunks)admin/form-builder/assets/js/components/field-text/template.php
(1 hunks)admin/form-builder/assets/js/components/field-textarea/index.js
(1 hunks)admin/form-builder/assets/js/components/field-textarea/template.php
(1 hunks)admin/form-builder/assets/js/components/field-visibility/index.js
(1 hunks)admin/form-builder/assets/js/components/field-visibility/template.php
(3 hunks)admin/form-builder/assets/js/components/form-checkbox_field/template.php
(1 hunks)admin/form-builder/assets/js/components/form-column_field/index.js
(4 hunks)admin/form-builder/assets/js/components/form-column_field/template.php
(1 hunks)admin/form-builder/assets/js/components/form-custom_hidden_field/template.php
(1 hunks)admin/form-builder/assets/js/components/form-dropdown_field/template.php
(1 hunks)admin/form-builder/assets/js/components/form-email_address/template.php
(1 hunks)admin/form-builder/assets/js/components/form-featured_image/template.php
(1 hunks)admin/form-builder/assets/js/components/form-fields-v4-1/index.js
(1 hunks)admin/form-builder/assets/js/components/form-fields-v4-1/template.php
(1 hunks)admin/form-builder/assets/js/components/form-fields/index.js
(1 hunks)admin/form-builder/assets/js/components/form-image_upload/template.php
(1 hunks)admin/form-builder/assets/js/components/form-multiple_select/template.php
(1 hunks)admin/form-builder/assets/js/components/form-post_content/template.php
(1 hunks)admin/form-builder/assets/js/components/form-post_excerpt/template.php
(1 hunks)admin/form-builder/assets/js/components/form-post_tags/template.php
(1 hunks)admin/form-builder/assets/js/components/form-post_title/template.php
(1 hunks)admin/form-builder/assets/js/components/form-radio_field/template.php
(1 hunks)admin/form-builder/assets/js/components/form-recaptcha/template.php
(1 hunks)admin/form-builder/assets/js/components/form-section_break/template.php
(1 hunks)admin/form-builder/assets/js/components/form-taxonomy/template.php
(3 hunks)admin/form-builder/assets/js/components/form-text_field/template.php
(1 hunks)admin/form-builder/assets/js/components/form-textarea_field/template.php
(1 hunks)admin/form-builder/assets/js/components/form-website_url/template.php
(1 hunks)admin/form-builder/assets/js/components/help-text/index.js
(1 hunks)admin/form-builder/assets/js/components/help-text/template.php
(1 hunks)admin/form-builder/assets/js/form-builder.js
(14 hunks)admin/form-builder/assets/js/mixins/add-form-field.js
(2 hunks)admin/form-builder/assets/js/mixins/form-field.js
(3 hunks)admin/form-builder/assets/js/mixins/global.js
(1 hunks)admin/form-builder/assets/js/mixins/option-field.js
(1 hunks)admin/form-builder/assets/less/form-builder.less
(4 hunks)admin/form-builder/assets/less/variables.less
(1 hunks)admin/form-builder/views/form-builder-v4.1.php
(1 hunks)admin/form-builder/views/form-builder.php
(2 hunks)admin/form-builder/views/settings-sidebar.php
(1 hunks)admin/html/form-settings-post.php
(1 hunks)assets/css/admin.css
(0 hunks)assets/css/frontend-forms.css
(2 hunks)assets/css/wpuf-form-builder.css
(4 hunks)assets/js-templates/form-components.php
(17 hunks)assets/js/wpuf-form-builder-components.js
(16 hunks)assets/js/wpuf-form-builder-mixins.js
(7 hunks)assets/js/wpuf-form-builder-wpuf-forms.js
(2 hunks)assets/js/wpuf-form-builder.js
(14 hunks)assets/less/admin.less
(0 hunks)assets/less/frontend-forms.less
(2 hunks)assets/vendor/selectize/js/standalone/selectize.js
(140 hunks)includes/Admin/Admin_Subscription.php
(1 hunks)includes/Admin/Forms/Admin_Form.php
(2 hunks)includes/Admin/Forms/Admin_Form_Builder.php
(7 hunks)includes/Admin/Forms/Post/Templates/Form_Template.php
(3 hunks)includes/Admin/Forms/Post/Templates/Post_Form_Template_Events_Calendar.php
(1 hunks)includes/Admin/Forms/Post/Templates/Post_Form_Template_Post.php
(9 hunks)includes/Admin/Forms/Post/Templates/Post_Form_Template_WooCommerce.php
(2 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/Ajax.php
(1 hunks)includes/Ajax/Admin_Form_Builder_Ajax.php
(2 hunks)includes/Assets.php
(1 hunks)includes/Fields/Field_Contract.php
(2 hunks)includes/Fields/Form_Field_Checkbox.php
(1 hunks)includes/Fields/Form_Field_Cloudflare_Turnstile.php
(1 hunks)includes/Fields/Form_Field_Column.php
(2 hunks)includes/Fields/Form_Field_Dropdown.php
(1 hunks)includes/Fields/Form_Field_Email.php
(1 hunks)includes/Fields/Form_Field_Featured_Image.php
(2 hunks)includes/Fields/Form_Field_Hidden.php
(1 hunks)includes/Fields/Form_Field_Image.php
(1 hunks)includes/Fields/Form_Field_MultiDropdown.php
(1 hunks)includes/Fields/Form_Field_Numeric.php
(0 hunks)includes/Fields/Form_Field_Post_Content.php
(1 hunks)includes/Fields/Form_Field_Post_Excerpt.php
(1 hunks)includes/Fields/Form_Field_Post_Tags.php
(1 hunks)includes/Fields/Form_Field_Post_Taxonomy.php
(1 hunks)includes/Fields/Form_Field_Post_Title.php
(3 hunks)includes/Fields/Form_Field_Radio.php
(1 hunks)includes/Fields/Form_Field_SectionBreak.php
(2 hunks)
⛔ Files not processed due to max files limit (14)
- includes/Fields/Form_Field_Text.php
- includes/Fields/Form_Field_Textarea.php
- includes/Fields/Form_Field_reCaptcha.php
- includes/Fields/Form_Pro_Upgrade_Fields.php
- includes/Free/Free_Loader.php
- includes/Frontend_Render_Form.php
- includes/Pro_Upgrades.php
- includes/Setup_Wizard.php
- languages/wp-user-frontend.pot
- package.json
- src/css/admin/form-builder.css
- tailwind.config.js
- tests/chrome_recordings/post form templates.json
- wpuf-functions.php
💤 Files with no reviewable changes (3)
- includes/Fields/Form_Field_Numeric.php
- assets/css/admin.css
- assets/less/admin.less
✅ Files skipped from review due to trivial changes (16)
- includes/Fields/Form_Field_MultiDropdown.php
- includes/Fields/Form_Field_Radio.php
- includes/Fields/Form_Field_Post_Tags.php
- includes/Fields/Form_Field_Post_Content.php
- admin/form-builder/assets/js/components/form-multiple_select/template.php
- includes/Fields/Form_Field_Image.php
- includes/Admin/template-parts/modal.php
- includes/Fields/Form_Field_Checkbox.php
- includes/Admin/Forms/Template_Post.php
- includes/Fields/Form_Field_Post_Taxonomy.php
- assets/js/wpuf-form-builder-wpuf-forms.js
- includes/Fields/Form_Field_Email.php
- includes/Admin/Forms/Post/Templates/Post_Form_Template_Events_Calendar.php
- includes/Fields/Form_Field_Dropdown.php
- includes/Fields/Field_Contract.php
- admin/form-builder/assets/js/components/field-range/template.php
🧰 Additional context used
🪛 Biome (1.9.4)
assets/js/wpuf-form-builder.js
[error] 636-636: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
assets/js/wpuf-form-builder-components.js
[error] 328-328: 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] 328-328: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 351-351: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 359-359: 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] 297-297: 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] 1680-1680: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
admin/form-builder/assets/js/form-builder.js
[error] 636-636: 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-fields-v4-1/index.js
[error] 135-135: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
admin/form-builder/assets/js/components/builder-stage-v4-1/index.js
[error] 141-141: 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] 141-141: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 164-164: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 172-172: 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] 110-110: 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/vendor/selectize/js/standalone/selectize.js
[error] 1206-1206: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 1410-1411: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 1734-1734: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.
(lint/suspicious/noPrototypeBuiltins)
[error] 2014-2014: 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] 2053-2054: 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] 2246-2246: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.
(lint/suspicious/noPrototypeBuiltins)
[error] 2402-2402: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.
(lint/suspicious/noPrototypeBuiltins)
[error] 2599-2599: 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] 2659-2659: 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] 2790-2790: 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] 2828-2828: 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] 2880-2880: 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] 2896-2896: 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] 3167-3167: 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] 3269-3269: 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] 3446-3446: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.
(lint/suspicious/noPrototypeBuiltins)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Run PHPCS inspection
🔇 Additional comments (158)
includes/Fields/Form_Field_SectionBreak.php (1)
13-13
: LGTM! Icon update is more semantically appropriate.The icon change from 'columns' to 'menu-alt-4' better represents a section break visually.
admin/form-builder/assets/js/components/form-textarea_field/template.php (2)
11-14
: LGTM! Clean and well-structured text editor implementation.The text editor component is properly conditionally rendered with clear prop bindings and improved formatting.
16-16
: Consider XSS risks with v-html directive.While the help text styling looks good, using
v-html
can expose your application to XSS attacks if the content is not properly sanitized.Please ensure that
field.help
content is sanitized before being rendered. Consider using a text-only alternative if HTML formatting is not required:- <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">{{ field.help }}</p>includes/Fields/Form_Field_Column.php (1)
13-13
: LGTM! Icon update is consistent with other form field classes.The icon name change from 'columns' to 'view-columns' provides better semantic clarity.
admin/form-builder/assets/js/components/field-visibility/index.js (1)
5-7
: LGTM! Enhanced component functionality with form field mixin.The addition of
wpuf_mixins.form_field_mixin
alongside the existingoption_field_mixin
improves the component's capabilities.admin/form-builder/assets/js/components/form-column_field/index.js (4)
5-6
: LGTM! Mixin integration enhances form field functionality.The addition of
wpuf_mixins.add_form_field
alongsideform_field_mixin
provides a good separation of concerns and reusable form field functionality.
30-30
: LGTM! Improved DOM selectors.The selectors have been refined to be more specific and maintainable:
- More precise column fields selector using
.wpuf-field-columns .wpuf-column-inner-fields
- Simplified button removal using
.wpuf-field-button
Also applies to: 63-63
57-57
: LGTM! More robust data retrieval.Using
data()
to get column information instead of parsing class names is a more reliable approach that reduces brittleness.
118-131
: LGTM! Well-structured computed properties.The new computed properties enhance maintainability:
action_button_classes
centralizes Tailwind CSS classes for consistent button stylingcolumnClasses
provides dynamic column class generation based on column countadmin/form-builder/assets/js/components/field-option-data/template.php (1)
2-6
: LGTM! Clean header structure with proper conditional rendering.The header section is well-organized with appropriate spacing and typography classes.
includes/Admin/Forms/Post/Templates/Pro_Form_Preview_EDD.php (1)
30-30
: LGTM! Good choice using SVG format.Switching to SVG format improves scalability and reduces asset size.
includes/Admin/Forms/Post/Templates/Post_Form_Template_Post.php (2)
18-18
: LGTM! Consistent SVG usage.The change to SVG format aligns with the project-wide image format standardization.
144-144
: LGTM! Consistent placeholder format.The change to curly brace placeholders ({login} / {register}) aligns with modern string template conventions.
includes/Admin/Forms/Post/Templates/Post_Form_Template_WooCommerce.php (2)
17-17
: LGTM! Consistent SVG usage.The change to SVG format maintains consistency across templates.
187-187
: LGTM! Consistent placeholder format.The message restriction format update aligns with the standardized curly brace placeholder pattern.
admin/form-builder/assets/js/components/field-textarea/template.php (2)
2-2
: LGTM! Consistent spacing applied to label.The addition of
wpuf-mb-2
class maintains consistent spacing between the label and the textarea field.
5-5
: LGTM! Enhanced textarea styling with dynamic class binding.The addition of
:class="builder_class_names('textareafield')"
allows for dynamic styling based on the field's state while maintaining the existing functionality.admin/form-builder/assets/js/components/field-textarea/index.js (1)
5-6
:✅ Verification successful
LGTM! Enhanced component with form field functionality.
The addition of
wpuf_mixins.form_field_mixin
alongsideoption_field_mixin
enhances the component with shared form field functionality while maintaining existing option field features.Let's verify the mixin integration:
🏁 Script executed:
#!/bin/bash # Description: Verify the form_field_mixin usage across components # and ensure it's properly defined # Check if form_field_mixin is defined rg -A 5 "form_field_mixin.*=" admin/form-builder/assets # Check consistent usage across components rg "wpuf_mixins.form_field_mixin" admin/form-builder/assets/js/componentsLength of output: 3507
Mixins integration verified: No further changes required.
After reviewing the code and verifying with the shell scripts, the usage and definition ofwpuf_mixins.form_field_mixin
are consistent across the project. Thefield-textarea
component properly integrates bothwpuf_mixins.option_field_mixin
andwpuf_mixins.form_field_mixin
, confirming that the component enhancements are correct.includes/Fields/Form_Field_Post_Title.php (2)
9-9
: Icon update improves semantic clarity.The icon change from 'header' to 'title' better represents the field's purpose.
97-97
:✅ Verification successful
Verify impact of adding 'required' to default options.
Adding 'required' to default options makes the field's required status configurable. Please ensure this change doesn't affect existing forms that might have custom handling for required fields.
🏁 Script executed:
#!/bin/bash # Search for any custom form configurations that might be affected rg -A 5 "get_default_option_settings.*required" --type phpLength of output: 576
Subject: Impact of adding 'required' to default options verified
The investigation shows that the only occurrence of adding
'required'
to the default options is inincludes/Fields/Form_Field_Post_Title.php
. No evidence was found of existing custom form handling that would be adversely impacted by this change. The change appears confined to making the required status configurable for this field, without interfering with any other form configurations.
- The script output only returned the modified snippet from
includes/Fields/Form_Field_Post_Title.php
.- No additional files or custom handling were detected regarding the
'required'
option viaget_default_option_settings
.Please review any form-specific overrides if they exist, but based on the current search, the change appears safe.
includes/Fields/Form_Field_Post_Excerpt.php (1)
11-11
: Icon update improves visual representation.The icon change from 'compress' to 'menu-alt-2' better represents an excerpt/summary field.
includes/Admin/Menu.php (2)
119-124
: LGTM: Initialization of template-related variables.The code properly initializes variables for post form templates, pro form previews, and blank form URL.
129-131
:❓ Verification inconclusive
Verify the early exit condition.
The early exit when
$registry
is empty might prevent users from seeing other UI elements. Ensure this is the intended behavior.
🏁 Script executed:
#!/bin/bash # Description: Check if there are any UI elements that should be visible even when $registry is empty # Search for template files that might be affected by this condition # Look for other template files in the same directory fd -e php -d includes/Admin/template-parts # Check for any references to these templates in the codebase rg -A 5 "template-parts"Length of output: 6266
Action: Confirm the intended early exit behavior on missing
$registry
.The code currently exits the loop immediately when
$registry
is falsy:if ( ! $registry ) { break; }Our search results show that key UI components—such as the modal template (
modal-v4.1.php
) referenced inincludes/Admin/Menu.php
—are conditionally included, which implies that this early exit may indeed be by design. However, it’s important to ensure that this conditional break does not unintentionally hide other intended UI elements that should render regardless of$registry
's state.Please verify:
- That no critical UI components are expected to be displayed even if
$registry
is empty.- That the early exit is fully aligned with the intended user experience in the admin interface.
includes/Fields/Form_Field_Featured_Image.php (2)
113-113
: LGTM! Appropriate exclusion of width option.The addition of 'width' to excluded options is logical since featured images typically don't need width configuration at the field level.
15-15
:❓ Verification inconclusive
Verify frontend compatibility of the new icon name.
The icon has been changed from 'file-image-o' to 'photograph' as part of a broader icon standardization effort. Please ensure that:
- The new icon name is supported by the icon library in use
- The icon renders correctly in the frontend
🏁 Script executed:
#!/bin/bash # Search for icon library configuration or usage rg -l "photograph" "resources/" "assets/"Length of output: 88
🏁 Script executed:
#!/bin/bash # Search for "photograph" across the entire repository rg -il "photograph"Length of output: 102
Action Required: Manually Verify the Frontend Compatibility of the "photograph" Icon
The icon property was updated from "file-image-o" to "photograph" in the featured image fields (and similarly in Form_Field_Image). Although the icon string now appears in these files, we could not automatically verify its support or rendering in the icon library configuration. Please manually confirm that the "photograph" icon is valid and correctly rendered in the frontend UI.
- Verify that the icon library in use supports "photograph" as a valid icon identifier.
- Check that the UI displays the updated icon properly in both the
Form_Field_Featured_Image.php
andForm_Field_Image.php
contexts.includes/Fields/Form_Field_Hidden.php (1)
13-13
:❓ Verification inconclusive
Verify the icon name exists in the icon library.
The icon name change from 'eye-slash' to 'eye-off' maintains semantic meaning and aligns with the icon standardization effort. However, let's verify that 'eye-off' exists in the icon library being used.
🏁 Script executed:
#!/bin/bash # Search for other occurrences of both old and new icon names # to ensure consistent migration and verify the icon exists in assets echo "Searching for old icon name 'eye-slash'..." rg --type php "eye-slash" echo -e "\nSearching for new icon name 'eye-off'..." rg --type php "eye-off" echo -e "\nSearching for icon definitions in asset files..." fd -e svg -e css -e scss -e less | xargs rg -l "eye-off"Length of output: 500
Action: Manually verify the "eye-off" icon in the asset library.
The icon update in
includes/Fields/Form_Field_Hidden.php
(line 13) replaces'eye-slash'
with'eye-off'
, which aligns with our broader icon standardization effort. Automated searches confirmed the code change but did not reveal any asset definitions (e.g., in SVG, CSS, SCSS, or LESS files) for"eye-off"
.Please ensure that:
- The
"eye-off"
icon is defined in the assets or available via the icon library.- The change is consistently applied across all relevant parts of the codebase.
includes/Admin/Forms/Admin_Form.php (1)
197-219
: Use a consistent condition naming convention.Lines 197, 201, 205, 209, 213, and 217 introduce several
v-show
conditions referencingactive_settings_tab
. Ensure that these IDs (#wpuf-metabox-settings
,#wpuf-metabox-settings-update
, etc.) align with both the Vue data and any references in your code or templates. This consistency avoids broken tab toggling or naming mismatches.Please confirm these elements exist and are spelled correctly in your referenced
.vue
or.php
files.admin/form-builder/assets/js/form-builder.js (6)
44-47
: Establish clarity on form-type logic.You're introducing
is_older_form
,is_post_form
, and a conditionalcurrent_panel
to handle older vs. new form behavior. Ensure that all relevant form builder actions downstream (e.g., event listeners, watchers) properly check these new states. Unit tests or integration tests should confirm the correct panel is shown for each form type.
170-174
: Ensure instructions remain relevant.The text blocks added around lines 170 and 174 guide users to enable “Show custom field data in the post content area.” Confirm this is still valid across WP versions or your plugin’s new front-end logic. The additional
imageUrl: wpuf_form_builder.lock_icon
at line 181 might also need a fallback or existence check iflock_icon
is missing.Also applies to: 181-181, 186-186, 188-188
422-430
: Initialize data properties with caution.These newly introduced properties (
isDirty
,shortcodeCopied
,logoUrl
, etc.) are important for multiple watchers and UI states. Thoroughly test to ensure they are updated in each scenario (saving forms, copying shortcodes, switching form tabs, etc.).
520-546
: Clipboard usage and tooltip consistency.This block sets up clipboards and tooltips for shortcodes. Check that the tooltip text reverts to the default message after a successful copy across all possible user flows. If there's a custom i18n string for copying, ensure it’s consistent with the rest of your codebase’s translations.
Also applies to: 556-591
616-616
: Tab switching logic.
setActiveSettingsTab
binds the.attr('href')
as the active index. Validate that an anchor link or hash-based approach doesn't conflict with internal or external routing, especially if future code tries to interpret the URL fragment.Also applies to: 631-632
736-738
: Guard setting changes.
switch_form_settings_pic_radio_item
updatesthis.form_settings[key] = value;
. If certain keys require special validation or data transformations, consider hooking them here or verifying user input.assets/js/wpuf-form-builder.js (3)
44-47
: Use consistent naming for older vs. new forms.
is_older_form
andis_post_form
control which panel is displayed. Ensure logic across the codebase references the same naming convention and doesn’t create confusion about what “older” means in future expansions.
244-244
: Resetting panels after deletion.Resetting
current_panel
whenever a field or column field is removed can disrupt the user experience if they’re actively editing a different field. Validate that your intended flow is to return to the main “fields” panel.Also applies to: 391-392
736-738
: Validate or sanitize incoming values.
switch_form_settings_pic_radio_item
setsthis.form_settings[key] = value;
. Confirm thatkey
andvalue
come from trusted sources to prevent unexpected errors or security concerns (for instance with HTML injection).assets/js/wpuf-form-builder-components.js (16)
41-41
: [Approved] Updated sortable handle selector
The revised selector for the sortable handle (.field-buttons .move
) looks correct and matches the intended draggable element.
188-213
: [Approved] Newbuilder-stage-v4-1
component definition
This newly introduced component is structurally consistent with the existing builder-stage. It retains similar properties, mixins, and computed fields, which helps maintain consistency across the UI.
214-264
: [Verify usage of jQuery sortable in Vue
While the jQuery UI logic here is acceptable, consider verifying that we don’t conflict with Vue reactivity. If possible, a purely Vue-based drag-and-drop solution could provide tighter integration with the store, though that may be out of scope for this PR.
317-365
: [Approved] Additional methods
The various helper methods for hidden fields, PRO previews, and reCaptcha checks appear consistent and straightforward. Good job.🧰 Tools
🪛 Biome (1.9.4)
[error] 328-328: 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] 328-328: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 351-351: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 359-359: 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)
372-373
: [Approved] Introducedform_field_mixin
tofield-checkbox
Mixing in form field logic is a clean approach to unify field behaviors.
606-606
: [Approved] Mergedfield_options
andform_field_mixin
Including both mixins ensures the options panel logic stays consistent with the form field store updates.
715-716
: [Approved] Additional mixin forfield-radio
Includingform_field_mixin
for radio fields aligns with the rest of the codebase.
774-778
: [Approved] Data object infield-select
DefiningshowOptions
andselectedOption
as local states looks good, ensuring better local control of the dropdown.
802-803
: [Approved]field-text
obtainsform_field_mixin
This addition helps unify text fields with the global store mechanism.
873-874
: [Approved]field-textarea
withform_field_mixin
Ensures the textarea field is consistent with the shared logic.
894-895
: [Approved]field-visibility
updates
Integrating the form field mixin is consistent with other fields.
1001-1002
: [Approved] Combined mixins in column field
Reusing add_form_field and form_field_mixin in a single array keeps the column field logic modular and consistent.
1026-1026
: [Approved] Additional jQuery selector forcolumnFields
Looks correct and ensures we can find the.wpuf-field-columns .wpuf-column-inner-fields
region.
1053-1053
: [Approved] Settingto_column
from the parent
This approach is fine for passing the target column index during drag events.
1059-1059
: [Approved] Removing stage button
Consistently removing.wpuf-field-button
matches the logic in the main stage.
1118-1127
: [Approved] Calculating column classes
This dynamic creation of['column-1', 'column-2', ...]
suits the user-defined columns well.assets/js-templates/form-components.php (32)
85-92
: [Approved] New “builder-stage-v4-1” template
This replacement offers a cleaner, modern UI with a helpful empty-state illustration. Good job.
210-255
: [Approved] Hidden-fields section
The design aligns with the main stage approach, providing uniform styling and control buttons for hidden fields.
260-265
: [Approved]panel-field-opt-checkbox
template
Introduces a modern layout with consistent spacing. The updated classes for margin and labeling are clean.
279-294
: [Approved] Changes for multi-select
Proper use of classes to style the<select>
element. The multiple attribute logic is consistent with the earlier approach.
298-433
: [Approved] Option data struct updates
Allows toggling “Show values” and “Sync values.” This is a neat approach for dynamic option labeling.
447-502
: [Approved] Enhanced advanced tab toggling
Segmenting out basic vs. advanced settings is well structured and easy to navigate.
570-595
: [Approved]field-select
improvements
Click-based display of options is well-handled. TheshowOptions
boolean state is clear.
598-622
: [Approved] Additional text field customization
Retaining the number variant plus hooks for focusout and keyup is consistent and flexible.
626-640
: [Approved]field-text-meta
Helps auto-generate meta keys from the label. This can save user time and reduce input errors.
643-648
: [Approved]field-textarea
block
The upgraded fully stylized text area matches your new design system.
652-710
: [Approved] Visibility-based conditional design
Using checkboxes for roles and subscription plans inside the new layout is a strong approach, especially if it’s stable with complex user roles.
739-776
: [Approved] Layout for checkbox fields
The classic inline vs. block approach is a nice user-friendly choice, consistent with the design.
794-919
: [Approved] The new column field template
Dividing columns with dynamic widths, plus handle-based drag control, is a well-structured approach.
922-931
: [Approved] Hidden field template
The updated placeholder usage and help text are consistent with the rest of the new UI.
939-952
: [Approved] Dropdown field
Ensures a well-labeled placeholder option with modern styling.
955-964
: [Approved] Email address field updates
Allows consistent styling with the rest of the form components.
990-1040
: [Approved] Sidebar form fields
The definition and toggling logic for panels remain user-friendly and consistent with the rest of the builder.
1042-1170
: [Approved]form-fields-v4-1
Introducing search functionality for form fields is a great UX improvement. The styled placeholders and dynamic filtering are nicely implemented.
1200-1218
: [Approved] Multi-select
Rendering multiple options in a block with a big range of styles is consistent with the rest.
1221-1249
: [Approved] Post content field updates
The new logic for optionally inserting photos or switching between text and rich editor is well integrated.
1252-1266
: [Approved] Post excerpt field
Mirrors the logic of post content with a streamlined design, including optional multiple editors.
1268-1281
: [Approved] Post tags field
The placeholder usage andhelp
text are consistent with your new design language.
1284-1295
: [Approved] Post title field
The updated class usage unifies it with the new styling approach across fields.
1298-1330
: [Approved] Radio field
Maintains the inline or block approach, consistent with the approach used in checkboxes.
1333-1343
: [Approved] reCaptcha
Shows placeholders or appropriate text depending on whether keys are set, matching variations from the existing logic.
1346-1365
: [Approved] Section break improvements
Supporting different divider styles is a nice usability enhancement, letting the user choose between standard or dashed.
1368-1415
: [Approved] Taxonomy field
Efficiently handles multiple display modes (select, AJAX, checkbox) in a single template with sorted terms.
1418-1427
: [Approved] Text field
The theming is consistent, using your new class-based approach for placeholders and sizing.
1430-1447
: [Approved] Textarea field
The distinction between rich and non-rich is well-coded, preserving the user’s preference while maintaining consistent stylings.
1450-1461
: [Approved] Website URL field
The placeholder and help text usage remain consistent, giving users a clear form experience.
1464-1474
: [Approved] New help-text
This minimal tooltip solution is a nice approach, demonstrating how to unify help text across different fields.
1477-1547
: [Approved] Text editor
The custom-coded mock of a TinyMCE-like interface is consistent with the admin’s approach, providing a realistic preview.includes/Admin/views/post-form.php (1)
1-3
: [Verify references to old action hook
You’ve replaceddo_action( 'wpuf_admin_form_builder' )
withwpuf_admin_form_builder_view
. Ensure any code hooking into the old action is also updated to the new hook or remains intentionally separate.admin/form-builder/assets/js/components/form-website_url/template.php (2)
9-9
: LGTM! Consistent help text styling.The help text styling is consistent with other form field components, using semantic HTML and utility classes for better maintainability.
4-4
:❓ Verification inconclusive
Verify the builder_class_names method availability.
The change from
class_names
tobuilder_class_names
suggests a new method implementation. Ensure this method is properly defined in the form field mixin.
🏁 Script executed:
#!/bin/bash # Search for builder_class_names method definition ast-grep --pattern 'builder_class_names'Length of output: 40
Verify the builder_class_names method implementation.
The change from
class_names('url')
tobuilder_class_names('url')
implies a new method should be present in the form field mixin or a related JavaScript module. The initialast-grep
search returned no output, so please re-run the above command (or verify manually) to confirm whetherbuilder_class_names
is defined. If the method is missing, it will need to be implemented to maintain consistent class binding behavior.
🏁 Script executed:
[run_scripts] #!/bin/bash # Re-run the search using ripgrep to capture both definitions and usages of builder_class_names rg "builder_class_names\\s*\\(" -n .Length of output: 8903
Action Required: Verify builder_class_names Implementation in Form Field Mixin
The updated usage of
builder_class_names('url')
in this template aligns with similar changes seen throughout the codebase. Automated searches confirm thatbuilder_class_names
is consistently used across multiple components (e.g., in field-checkbox, field-option-data, and form-email_address templates). However, the automated search did not directly reveal its definition. Please manually verify that thebuilder_class_names
method is properly implemented in the form field mixin (or the related utility module) to ensure the method’s availability and consistent behavior across all components.admin/form-builder/assets/js/components/form-text_field/template.php (1)
7-9
: LGTM! Consistent implementation.The changes maintain consistency with other form field components:
- Using
builder_class_names
for class binding- Consistent help text styling with utility classes
admin/form-builder/assets/js/components/form-custom_hidden_field/template.php (1)
4-4
:❓ Verification inconclusive
Verify the class name change impact.
The class name has changed from 'textfield' to 'text_hidden'. While this might better reflect the field's purpose, ensure this change doesn't break any existing styles.
🏁 Script executed:
#!/bin/bash # Search for references to both class names rg "text_hidden|textfield" --type cssLength of output: 15547
Action: Confirm the styling impact of the updated class name.
The custom hidden field now uses "text_hidden" instead of "textfield". A CSS scan didn’t reveal any explicit rules targeting either class name directly. However, take note that in assets/css/admin/form-builder.css a
-webkit-appearance: textfield;
property exists—if this property was meant to apply specific styling to text fields, it may need reconsideration for hidden fields. Please verify that the builder_class_names helper and any related style dependencies accommodate the new class name without adverse side effects.admin/form-builder/assets/js/components/form-post_tags/template.php (2)
4-5
: LGTM! The class binding and styling updates look good.The changes improve the styling consistency by:
- Using the new
builder_class_names
method for dynamic class binding- Adding Tailwind CSS utility classes for better styling control
11-11
: LGTM! The help text element update improves semantics.The change from
<span>
to<p>
improves semantic HTML structure while maintaining consistent styling with other form fields.admin/form-builder/assets/js/components/form-post_excerpt/template.php (1)
13-13
: LGTM! The help text element update improves semantics.The change from
<span>
to<p>
improves semantic HTML structure while maintaining consistent styling with other form fields.admin/form-builder/assets/js/components/field-multiselect/template.php (2)
1-1
: LGTM! The conditional rendering update improves performance.The change from
v-show
tov-if
removes the element from the DOM when not needed, which is more efficient than just hiding it.
8-8
: LGTM! The styling updates enhance user experience.The changes improve the styling by:
- Adding full width and proper spacing
- Adding primary border color
- Adding proper z-index for dropdowns
- Adding visual feedback for checked state
Also applies to: 12-15
admin/form-builder/assets/js/components/field-checkbox/template.php (1)
1-1
: LGTM! The styling updates improve layout consistency.The changes enhance the layout by:
- Adding proper bottom margin to the container
- Adding proper top margin to list items
- Using the new
builder_class_names
method for dynamic class bindingAlso applies to: 6-6, 8-8
admin/form-builder/assets/js/components/field-radio/index.js (1)
4-7
:❓ Verification inconclusive
LGTM! Verify mixin usage across components.
The addition of
form_field_mixin
aligns with the broader enhancement of form field components.Let's verify the consistent usage of
form_field_mixin
across other form field components:
🏁 Script executed:
#!/bin/bash # Description: Check for consistent mixin usage across form field components. rg -A 2 "mixins: \[" "admin/form-builder/assets/js/components/field-"Length of output: 156
Field Mixin Consistency Review
The update to
admin/form-builder/assets/js/components/field-radio/index.js
now correctly includes bothwpuf_mixins.option_field_mixin
and the newly addedwpuf_mixins.form_field_mixin
. However, our initial check for consistent usage across other form field components returned an error because the search was attempted in a non-existent (or misnamed) directory (admin/form-builder/assets/js/components/field-
).Please verify manually that:
- Other form field component files (likely under directories such as
admin/form-builder/assets/js/components/field-radio
,field-checkbox
, etc.) also incorporatewpuf_mixins.form_field_mixin
as intended.- The search path is corrected (for instance, try using a more general search such as
rg "wpuf_mixins.form_field_mixin" "admin/form-builder/assets/js/components"
) to ensure consistency across the codebase.admin/form-builder/assets/js/components/field-text-meta/template.php (2)
1-7
: LGTM! Enhanced accessibility and layout structure.The changes improve accessibility by adding the
for
attribute and enhance the layout with flex container.
8-12
:✅ Verification successful
Verify Tailwind CSS classes.
The input field uses several Tailwind CSS utility classes. Ensure these classes are properly configured in the Tailwind config.
🏁 Script executed:
#!/bin/bash # Description: Check Tailwind configuration for the used classes. rg -l "tailwind" . | while read -r file; do if [[ "$file" == *"config"* ]]; then echo "Found potential Tailwind config in: $file" cat "$file" fi doneLength of output: 1754
Tailwind configuration verified.
The Tailwind config intailwind.config.js
properly defines the custom prefix (wpuf-
) and covers the paths where your assets reside. This confirms that all the utility classes used in the input field (e.g.,wpuf-block
,wpuf-min-w-full
, etc.) are correctly configured. No changes are required.admin/form-builder/assets/js/components/field-text/index.js (1)
4-7
: LGTM! Consistent mixin enhancement.The addition of
form_field_mixin
maintains consistency with other form field components.admin/form-builder/assets/js/components/field-select/index.js (1)
8-13
:❓ Verification inconclusive
Verify template implementation for custom dropdown.
The new data properties suggest a custom dropdown implementation. Ensure the template properly handles:
- Toggle visibility with
showOptions
- Update selection with
selectedOption
- Keyboard navigation
- ARIA attributes for accessibility
Let's check the template implementation:
🏁 Script executed:
#!/bin/bash # Description: Check template implementation for the custom dropdown. rg -A 10 "tmpl-wpuf-field-select" "admin/form-builder/assets/js/components/field-select/template.php"Length of output: 99
Action Required: Manually Verify Custom Dropdown Template Implementation
Ensure that the template in
admin/form-builder/assets/js/components/field-select/template.php
correctly supports the new custom dropdown features. Specifically, verify that it:
- Toggles dropdown visibility using
showOptions
- Updates the selected option via
selectedOption
- Supports keyboard navigation
- Implements proper ARIA attributes for accessibility
Since the initial
rg
command did not return any output, please perform a manual check or re-run an appropriate verification to confirm that these functionalities are implemented.admin/form-builder/assets/js/components/field-text/template.php (1)
2-8
: Great improvements to accessibility and layout!The changes enhance the component by:
- Properly linking label to input field using
for
attribute- Using flex container for better alignment
- Adding proper spacing with Tailwind CSS classes
admin/form-builder/assets/js/components/form-section_break/template.php (1)
1-18
: Excellent enhancement to section break styling!The changes provide:
- Two distinct section break styles (regular and dashed)
- Better visual hierarchy with proper spacing
- Responsive layout using Tailwind CSS classes
admin/form-builder/assets/js/components/field-checkbox/index.js (1)
4-7
:❓ Verification inconclusive
LGTM! Standardizing form field behavior.
The addition of
wpuf_mixins.form_field_mixin
aligns with the standardization of form field components, while preserving the existing option field functionality.Let's verify that other form field components also use this mixin:
🏁 Script executed:
#!/bin/bash # Search for other form field components using form_field_mixin ast-grep --pattern $'mixins: [ $$$ wpuf_mixins.form_field_mixin $$$ ]'Length of output: 77
Action Required: Manual Verification of Form Field Mixin Usage
The code in admin/form-builder/assets/js/components/field-checkbox/index.js correctly adds the
wpuf_mixins.form_field_mixin
to standardize form field behavior. However, the automated search command for other form field components using this mixin did not return any output.Please manually verify that all relevant form field components across the codebase also include
wpuf_mixins.form_field_mixin
to ensure consistency.
- Action: Review and confirm that each applicable form field component (e.g., other files under admin/form-builder/assets/js/components/) has been updated to include the mixin.
admin/form-builder/assets/js/components/form-featured_image/template.php (2)
4-15
: LGTM! Enhanced UI with modern styling and visual feedback.The changes improve the user interface by:
- Adding Tailwind CSS classes for consistent styling
- Including an SVG icon for better visual feedback
- Using semantic HTML structure
19-19
: LGTM! Improved help text structure.Changed help text from
<span>
to<p>
for better semantics and added Tailwind classes for consistent styling.admin/form-builder/assets/js/components/form-image_upload/template.php (1)
23-23
: LGTM! Improved help text structure.Changed help text from
<span>
to<p>
for better semantics and added Tailwind classes for consistent styling.admin/form-builder/assets/js/components/form-checkbox_field/template.php (3)
2-17
: LGTM! Well-structured vertical checkbox layout.The vertical layout implementation with proper spacing and alignment using Tailwind CSS classes looks good. The conditional rendering based on
field.inline
is correctly implemented.
19-34
: LGTM! Inline checkbox layout with consistent spacing.The inline layout implementation with proper margin and alignment looks good. The use of utility classes for styling is consistent with the design system.
36-36
: LGTM! Help text styling is consistent.The help text styling using Tailwind CSS classes for margin and text color is consistent with the design system.
admin/form-builder/assets/js/components/field-radio/template.php (3)
2-6
: LGTM! Well-structured title section with help text.The title section with help text is well-structured and properly aligned using Tailwind CSS classes.
7-20
: LGTM! Vertical radio layout with proper spacing.The vertical layout implementation with proper gap and margin looks good. The class bindings are correctly implemented.
22-39
: LGTM! Inline radio layout with dynamic margin.The inline layout implementation with dynamic margin based on index looks good. The use of utility classes for styling is consistent.
admin/form-builder/assets/js/components/form-taxonomy/template.php (5)
2-6
: LGTM! Select element with proper class binding.The select element's class binding using
builder_class_names
is correctly implemented. The missing closing tag has been added.
8-17
: LGTM! Ajax select with proper class binding.The ajax select element's class binding using
builder_class_names
is correctly implemented.
19-26
: LGTM! Multiselect with proper class binding.The multiselect element's class binding using
builder_class_names
is correctly implemented.
37-45
: LGTM! Input element with dynamic bindings.The input element's class binding and dynamic attributes for placeholder and size are correctly implemented.
46-46
: LGTM! Help text styling is consistent.The help text styling using Tailwind CSS classes for margin and text color is consistent with the design system.
admin/form-builder/assets/js/components/field-options/template.php (3)
1-1
: LGTM! Consistent spacing improvements.The addition of
wpuf-px-6
andwpuf-mt-6
classes provides consistent padding and margin spacing.Also applies to: 9-9
10-16
: LGTM! Enhanced interactive feedback.The dynamic class bindings provide clear visual feedback for the basic settings section:
- Color changes based on section state
- Hover cursor indication
- Consistent text sizing
- Proper spacing
32-38
: LGTM! Consistent styling pattern.The advanced settings section follows the same styling pattern as basic settings, maintaining UI consistency.
admin/form-builder/assets/js/components/form-fields/index.js (1)
26-26
: LGTM! Enhanced drag-and-drop functionality.Adding
#form-preview-stage
toconnectToSortable
improves the user experience by allowing direct dragging to the stage container.admin/form-builder/assets/js/mixins/add-form-field.js (3)
20-31
: LGTM! Enhanced error feedback.The improved error modal provides better user feedback with:
- Clear visual styling
- Descriptive message
- Custom image
- Proper button styling
57-61
: LGTM! Clean pro feature detection.The
is_pro_preview
method provides a clean way to check pro features.
65-67
: LGTM! Consistent button styling.The
action_button_classes
computed property ensures consistent button styling across the interface.admin/form-builder/assets/js/mixins/form-field.js (2)
36-66
: LGTM! Comprehensive field styling system.The
builder_class_names
method provides a robust styling system with:
- Type-specific styling
- Consistent base classes
- Proper spacing and colors
- Responsive design classes
7-10
:❓ Verification inconclusive
Verify the impact of the default field prop change.
The change from an empty object to
{ key: 'value' }
as the default value might affect field initialization in components using this mixin.
🏁 Script executed:
#!/bin/bash # Search for components using this mixin to verify impact ast-grep --pattern 'mixins: [ $$$ wpuf_mixins.form_field_mixin $$$ ]'Length of output: 77
Action: Manually verify the mixin’s usage and its impact on field initialization
The change from an empty object to
{ key: 'value' }
as the default value could potentially affect how fields are initialized in components using this mixin. However, our automated search for instances ofwpuf_mixins.form_field_mixin
did not yield any results. To proceed safely:
- Manually check if any components import and use this mixin.
- Confirm that none of these components rely on the default being an empty object.
- Verify that the new default does not lead to unintended side effects in field behavior.
Please review these areas carefully before merging.
admin/form-builder/assets/js/components/field-option-data/index.js (1)
8-11
: LGTM! Enhanced field functionality with form_field_mixin.The addition of
form_field_mixin
alongsideoption_field_mixin
provides better separation of concerns and reusability.admin/form-builder/assets/js/components/field-options/index.js (1)
7-7
: LGTM! Improved mixin implementation.The change to array format for mixins follows Vue.js best practices and makes the code more maintainable.
includes/Ajax.php (2)
31-31
: LGTM! Improved method naming.The method name change for post taxonomies improves code clarity and follows better naming conventions.
32-32
:❓ Verification inconclusive
Verify error handling for the new roles endpoint.
The new AJAX action for roles should include proper error handling and role capability checks.
🏁 Script executed:
#!/bin/bash # Check if the get_roles method includes proper error handling and capability checks ast-grep --pattern 'function get_roles() { $$$ if (!current_user_can($_)) { $$$ } $$$ }'Length of output: 102
Action: Manually Verify Error Handling in the
get_roles
EndpointThe automated search didn’t return any evidence of error handling or role capability checks within the
get_roles
method. Please review the implementation inAjax/Admin_Form_Builder_Ajax.php
manually to ensure that:
- Proper error handling (for example, returning a
WP_Error
or similar response) is implemented.- There is a check using
current_user_can
(or an equivalent capability check) to restrict access for unauthorized users.If these controls are missing, consider adding them to ensure robust and secure AJAX interactions.
Lib/Appsero/Client.php (1)
168-168
:✅ Verification successful
Verify the impact of
get_plugin_data
parameter changes.The addition of parameters to
get_plugin_data
modifies how plugin data is retrieved:
true
: Returns markup in the plugin datafalse
: Disables translation of the plugin data
🌐 Web query:
What are the implications of setting markup=true and translate=false in WordPress get_plugin_data function?
💡 Result:
The
get_plugin_data
function in WordPress retrieves plugin metadata and behaves differently based on its$markup
and$translate
parameters. Here’s how these settings impact functionality:Implications of
$markup = true
- HTML Formatting: Adds markup like hyperlinks to fields such as
AuthorURI
orPluginURI
[1][2][4].
Example: Author names become clickable links if their URI exists.- Display Readiness: Returns data pre-formatted for admin interfaces or frontend displays[1][3].
- Unnecessary Overhead: Avoid using this if you need raw data for processing or comparisons[4].
Implications of
$translate = false
- Untranslated Strings: Returns plugin metadata exactly as written in the plugin’s header (e.g.,
Plugin Name: My Plugin
instead of localized versions)[1][3][8].- Performance: Skips loading translation files or using localization functions like
__()
[3][8].- Compatibility: Critical for avoiding "translation loaded too early" errors in WordPress 6.7+, where translations must load after the
init
hook[5][8].
Example usage:// Retrieve raw data without triggering translations $plugin_data = get_plugin_data(__FILE__, true, false);Key Tradeoffs
Parameter Use Case Risk if Misused $markup=true
Displaying plugin info in UIs Inconsistent formatting in non-HTML contexts $translate=false
Early code execution (e.g., defining constants) Untranslated text in user-facing contexts For modern WordPress (6.7+), always set
$translate=false
when callingget_plugin_data
outside translation-safe hooks (e.g.,init
) to prevent debug notices[5][8]. Use$markup=true
selectively based on display needs[1][4].Citations:
- 1: https://www.ensuredomains.com/codex/platform/wordpress/functions/get_plugin_data/
- 2: https://pexetothemes.com/wordpress-functions/get_plugin_data/
- 3: https://hitchhackerguide.com/2011/02/12/get_plugin_data/
- 4: https://wpseek.com/function/get_plugin_data/
- 5: https://theme.co/forum/t/after-upgrade-wordpress-6-7/111262
- 6: https://developer.wordpress.org/reference/functions/_get_plugin_data_markup_translate/
- 7: https://pexetothemes.com/wordpress-functions/get_plugins/
- 8: https://make.wordpress.org/core/2024/10/21/i18n-improvements-6-7/
- 9: https://github.com/WordPress/WordPress/blob/master/wp-settings.php
- 10: https://developer.wordpress.org/reference/functions/get_plugin_data/
Impact Verified: The parameters for get_plugin_data are used appropriately
The use of
get_plugin_data( $this->file, true, false );
in Lib/Appsero/Client.php on line 168 is aligned with WordPress best practices:
$markup = true
:
- Returns the plugin data with HTML formatting (e.g., clickable links for the author or plugin URI) which is ideal for UI display.
- Be mindful if raw data is needed for logic or comparisons, as the markup could add unnecessary overhead.
$translate = false
:
- Ensures the plugin metadata is returned as is, bypassing localization.
- This helps avoid potential issues (such as "translation loaded too early" warnings) in WordPress 6.7+ when calling get_plugin_data outside translation-safe hooks.
Overall, the parameters are correctly set for scenarios where formatted display is needed and early translation loading must be avoided. No changes appear necessary unless the context of usage demands raw (non-marked-up or translated) data.
includes/Fields/Form_Field_Cloudflare_Turnstile.php (1)
41-48
: LGTM! Improved HTML structure and styling consistency.The changes enhance the code by:
- Wrapping the turnstile div in a semantic list item
- Adding the
wpuf-fields
class for consistent styling with other form fieldsadmin/form-builder/views/form-builder.php (2)
42-42
: LGTM!The indentation fix improves code readability.
59-59
:❓ Verification inconclusive
Verify jQuery UI draggable initialization.
The added classes suggest integration with jQuery UI draggable functionality. Ensure that the draggable behavior is properly initialized.
Run the following script to verify the draggable initialization:
🏁 Script executed:
#!/bin/bash # Description: Search for jQuery UI draggable initialization for form switcher. # Test: Search for draggable initialization. Expect: jQuery UI draggable setup code. rg -A 5 'form-switcher.*draggable'Length of output: 36
Action Required: Verify jQuery UI Draggable Initialization
The initial search for a "form-switcher" draggable initialization did not return any results. Please confirm that the jQuery UI draggable functionality for form builder elements (i.e., the
<li>
elements with the classesui-draggable
andui-draggable-handle
) is properly initialized. This may involve one or more of the following steps:
- Locate Initialization Code: Verify in your JavaScript files (or inline scripts) that jQuery UI’s
.draggable()
method is being called on the appropriate selectors (e.g., elements with.ui-draggable
).- Update if Missing: If no initialization is found, consider adding the necessary script to enable the draggable behavior or updating existing scripts to include the initialization.
If you're not certain where the initialization should occur, a further manual inspection or a more generic codebase search (for instance, for occurrences of
.draggable(
) might be necessary to ensure the feature works as expected.admin/form-builder/assets/js/components/form-fields-v4-1/template.php (3)
1-34
: LGTM! Well-structured search component with clear visual feedback.The search component is well-implemented with:
- Dynamic filtering using v-model
- Clear visual feedback with SVG icons
- Proper accessibility attributes
35-110
: LGTM! Well-organized form fields panel with proper validation.The form fields panel implementation:
- Uses collapsible sections for better organization
- Implements proper validation and premium feature checks
- Provides clear visual feedback for different states
112-125
: LGTM! User-friendly call-to-action section.The call-to-action section is well-designed with:
- Clear messaging
- Proper link to external suggestion page
- Consistent styling with the rest of the UI
includes/Ajax/Admin_Form_Builder_Ajax.php (3)
80-129
: LGTM! Method renamed for backward compatibility.The old method is preserved with a new name to maintain backward compatibility.
131-185
: LGTM! Updated HTML structure with modern styling.The new method improves the UI with:
- Modern Tailwind CSS classes
- Better semantic HTML structure
- Vue.js class bindings
187-210
: LGTM! Well-implemented roles selector.The new method provides a user-friendly interface for role selection with:
- Clear labeling
- Multiple selection support
- Consistent styling
includes/Admin/Forms/Post/Templates/Form_Template.php (3)
108-110
: LGTM! Updated modal template version.The modal template has been updated to version 4.1, aligning with the new UI changes.
19-19
:❓ Verification inconclusive
Verify impact of commented-out action.
The admin footer action for rendering post form templates has been disabled. This might affect the form template functionality.
Run the following script to verify if the templates are rendered elsewhere:
🏁 Script executed:
#!/bin/bash # Description: Search for alternative template rendering implementations. # Test: Search for template rendering. Expect: Alternative implementation. rg -A 5 'render_post_form_templates'Length of output: 1095
Action Required: Verify Impact of Disabled Admin Footer Rendering
We confirmed by searching that the
add_action
hookingrender_post_form_templates
toadmin_footer
remains commented out and no alternative hook for invoking this method was found. The method itself is still defined inincludes/Admin/Forms/Post/Templates/Form_Template.php
, but there is no evidence that it's being triggered elsewhere, which could affect the intended template rendering in the admin area.
- If the removal of the admin footer hook is intentional, consider cleaning up the commented code and ensuring that template rendering is handled by a new mechanism.
- If this change was inadvertent, verify that the post form templates are rendered as expected on the admin side.
85-85
:❓ Verification inconclusive
Verify stylesheet dependency.
The stylesheet has been changed from
wpuf-form-builder
towpuf-admin-form-builder
. Ensure the new stylesheet is properly registered.Run the following script to verify the stylesheet registration:
🏁 Script executed:
#!/bin/bash # Description: Search for stylesheet registration. # Test: Search for stylesheet registration. Expect: Registration of wpuf-admin-form-builder. rg -A 5 'wp_register_style.*wpuf-admin-form-builder'Length of output: 54
Verify new stylesheet registration
The enqueue call for the new stylesheet (‘wpuf-admin-form-builder’) is present on line 85 of
includes/Admin/Forms/Post/Templates/Form_Template.php
, but our initial search for a correspondingwp_register_style
call did not return any matches. This may indicate one of the following:
- The stylesheet registration might be missing.
- It could be registered dynamically or in a different file/hook not captured by the initial static search.
Action points:
- Verify Registration: Please manually verify that there is a proper registration of
'wpuf-admin-form-builder'
(usingwp_register_style
) in the codebase. Look for any code that registers this stylesheet—if it’s conditionally or dynamically registered, ensure that it runs before this enqueue call.- Double-Check Dependencies: If the registration occurs in a central file or through an action hook, confirm that it is properly loaded before
Form_Template.php
is executed.admin/form-builder/assets/js/components/form-column_field/template.php (1)
46-46
:❓ Verification inconclusive
Verify the purpose of the empty overlay div.
There's an empty div with absolute positioning that overlays the entire field. This could potentially block user interactions.
🏁 Script executed:
#!/bin/bash # Search for any JavaScript event handlers or documentation that explains the purpose of this overlay rg -A 5 "wpuf-absolute wpuf-w-full wpuf-h-full wpuf-z-10" admin/form-builder/assets/js/Length of output: 1725
Action Required: Clarify the Purpose of the Overlay Element
The empty overlay div appears in both the form-column_field and builder-stage-v4-1 templates, yet no associated JavaScript event handlers or documentation explain its intent. This element, which overlays the entire field due to its absolute positioning, could block user interactions if not managed properly. Please review whether this overlay is necessary and either:
- Add inline documentation/comment explaining its purpose and interaction behavior, or
- Remove it if it does not serve a clear function in the UI.
includes/Assets.php (1)
109-181
: LGTM! The style array is well-structured and follows best practices.The changes maintain proper dependency management and consistent formatting. The new 'admin-form-builder' style is correctly integrated with appropriate dependencies.
includes/Admin/Forms/Admin_Form_Builder.php (1)
11-18
: LGTM! Well-documented constant definition.The constant PRO_FIELD_ASSETS is properly documented with PHPDoc and follows WordPress naming conventions.
includes/Admin/Posting.php (1)
39-50
: LGTM! Well-implemented asset dequeuing.The dequeue_assets method correctly checks the current screen and handles pro version comparison.
admin/form-builder/views/settings-sidebar.php (1)
284-302
: LGTM! Well-structured field rendering function.The wpuf_render_settings_field function properly handles field types and security.
includes/Admin/Admin_Subscription.php (1)
251-251
: LGTM! Improved error handling for billing amount.The change enhances robustness by adding null-safety check and proper type casting:
- Prevents undefined index errors with
isset()
- Ensures numeric type with
(float)
casting- Provides safe default of
0
admin/form-builder/assets/less/variables.less (1)
9-9
: LGTM! Added primary brand color variable.The new
@wpufPrimary
variable follows naming conventions and will help maintain consistent branding across the UI.assets/css/wpuf-form-builder.css (3)
200-200
: LGTM! Updated dropdown active state color.Uses the new primary color for better brand consistency.
540-541
: LGTM! Enhanced dropzone visibility.The new colors provide better contrast and visual feedback:
- Light green background (
#f0fdf4
) for clear target area- Green border (
#4ade80
) for distinct boundaries
857-857
: LGTM! Improved modal responsiveness.Using
100vh
ensures the modal adapts to different viewport heights.admin/form-builder/assets/less/form-builder.less (3)
269-269
: LGTM! Using new primary color variable.Leverages the new
@wpufPrimary
variable for consistent branding.
677-678
: LGTM! Enhanced dropzone styling.Improves visual feedback with semantic colors.
789-789
: LGTM! Adjusted panel field spacing.Using
2rem
provides more consistent spacing between fields.assets/vendor/selectize/js/standalone/selectize.js (2)
670-693
: Cosmetic Formatting in thehighlight
Function
The code changes in this block (within thehighlight
function) focus solely on reorganizing whitespace and improving readability. There are no logic or functional changes here.🧰 Tools
🪛 Biome (1.9.4)
[error] 683-683: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.(lint/suspicious/noRedundantUseStrict)
1-3834
: Overall Evaluation of Cosmetic Changes
The modifications throughout this vendor file are primarily cosmetic—aimed at removing extraneous blank lines, organizing the code better, and enhancing readability. There are no behavioral changes to the Selectize functionality. Before merging, verify that any additional refactoring (especially changes to debug logging or the use of modern JavaScript idioms) does not conflict with backward compatibility requirements of this third‑party component.🧰 Tools
🪛 Biome (1.9.4)
[error] 60-60: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 96-96: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 408-408: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 505-506: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 600-600: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 617-618: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 641-641: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 683-683: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.(lint/suspicious/noRedundantUseStrict)
[error] 743-743: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 953-954: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 1143-1145: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 1147-1149: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 1206-1206: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 1215-1215: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 1410-1411: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 1442-1442: Do not shadow the global "escape" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
[error] 1446-1446: Do not shadow the global "escape" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
[error] 1449-1449: Do not shadow the global "escape" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
[error] 1452-1452: Do not shadow the global "escape" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
[error] 1498-1498: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 1604-1605: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 1633-1635: This case is falling through to the next case.
Add a
break
orreturn
statement to the end of this case to prevent fallthrough.(lint/suspicious/noFallthroughSwitchClause)
[error] 1646-1647: This case is falling through to the next case.
Add a
break
orreturn
statement to the end of this case to prevent fallthrough.(lint/suspicious/noFallthroughSwitchClause)
[error] 1705-1705: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 1734-1734: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 1753-1753: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 1802-1803: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 1890-1891: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 1963-1963: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 2225-2225: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 2227-2227: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 2228-2228: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 2246-2246: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 2296-2296: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 2361-2362: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 2402-2402: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 2432-2432: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 2604-2604: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 2677-2677: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 3091-3092: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 3202-3204: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 3232-3233: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 3446-3446: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
[error] 117-117: 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] 351-351: 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] 581-581: 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] 608-608: 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] 639-639: 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] 1140-1140: 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] 1431-1431: 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] 1505-1505: 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] 1619-1620: 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] 1704-1704: 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] 1751-1751: 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] 1867-1867: 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] 1949-1949: 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] 2014-2014: 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] 2053-2054: 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] 2075-2076: 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] 2154-2154: 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] 2335-2338: 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] 2421-2421: 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] 2490-2491: 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] 2508-2509: 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] 2599-2599: 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] 2659-2659: 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] 2790-2790: 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] 2828-2828: 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] 2880-2880: 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] 2896-2896: 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] 2937-2937: 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] 2969-2969: 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] 3042-3042: 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] 3086-3087: 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] 3105-3105: 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] 3154-3154: 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] 3167-3167: 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] 3183-3183: 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] 3213-3213: 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] 3269-3269: 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] 3285-3285: 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)
$( this.$el ).tooltip({ | ||
title: this.text, | ||
placement: 'auto top' | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix tooltip placement and add cleanup.
The current implementation has several issues:
- Hardcoded placement ignores the
placement
prop. - Missing tooltip cleanup in the
destroyed
hook.
mounted: function () {
$( this.$el ).tooltip({
title: this.text,
- placement: 'auto top'
+ placement: this.placement
});
-}
+},
+
+destroyed: function () {
+ // Clean up tooltip to prevent memory leaks
+ $( this.$el ).tooltip('dispose');
+}
📝 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.
$( this.$el ).tooltip({ | |
title: this.text, | |
placement: 'auto top' | |
}); | |
mounted: function () { | |
$( this.$el ).tooltip({ | |
title: this.text, | |
placement: this.placement | |
}); | |
}, | |
destroyed: function () { | |
// Clean up tooltip to prevent memory leaks | |
$( this.$el ).tooltip('dispose'); | |
} |
@@ -110,6 +110,7 @@ public function get_field_props() { | |||
$props = [ | |||
'input_type' => 'text', | |||
'is_meta' => 'no', | |||
'required' => 'yes', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Breaking change: Post title is now mandatory.
Setting 'required' to 'yes' makes the post title field mandatory by default. While this aligns with typical post requirements, it's a breaking change that could affect existing forms.
Consider:
- Adding a migration script for existing forms
- Making this configurable via a setting
- Adding documentation about this change
includes/Admin/Forms/Admin_Form.php
Outdated
<!-- <a href="#wpuf-metabox-settings" | ||
:class="active_settings_tab === '#wpuf-metabox-settings' ? 'nav-tab-active' : ''" | ||
class="nav-tab"><?php // esc_html_e( 'Post Settings', 'wp-user-frontend' ); ?></a> | ||
<a href="#wpuf-metabox-settings-update" | ||
:class="active_settings_tab === '#wpuf-metabox-settings-update' ? 'nav-tab-active' : ''" | ||
class="nav-tab"><?php // esc_html_e( 'Edit Settings', 'wp-user-frontend' ); ?></a> | ||
<a href="#wpuf-metabox-submission-restriction" | ||
:class="active_settings_tab === '#wpuf-metabox-submission-restriction' ? 'nav-tab-active' : ''" | ||
class="nav-tab"><?php // esc_html_e( 'Submission Restriction', 'wp-user-frontend' ); ?></a> | ||
<a href="#wpuf-metabox-settings-payment" | ||
:class="active_settings_tab === '#wpuf-metabox-settings-payment' ? 'nav-tab-active' : ''" | ||
class="nav-tab"><?php // esc_html_e( 'Payment Settings', 'wp-user-frontend' ); ?></a> | ||
<a href="#wpuf-metabox-settings-display" | ||
:class="active_settings_tab === '#wpuf-metabox-settings-display' ? 'nav-tab-active' : ''" | ||
class="nav-tab"><?php // esc_html_e( 'Display Settings', 'wp-user-frontend' ); ?></a> | ||
<a href="#wpuf-metabox-post_expiration" | ||
:class="active_settings_tab === '#wpuf-metabox-post_expiration' ? 'nav-tab-active' : ''" | ||
class="nav-tab"><?php // esc_html_e( 'Post Expiration', 'wp-user-frontend' ); ?></a>--> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove or justify large commented-out code blocks.
These lines comment out the old tab navigation. If the new Vue-based navigation fully replaces it, consider removing the commented-out code to maintain cleaner source files. If you plan to restore or reference it later, add a clear comment describing its future use or revert strategy.
-<!-- <a href="#wpuf-metabox-settings"
- ...
- class="nav-tab"><?php // esc_html_e( 'Post Settings', 'wp-user-frontend' ); ?></a>-->
+// If needed for reference, move these lines to documentation or remove entirely to reduce clutter.
Committable suggestion skipped: line range outside the PR's diff.
setActiveSettingsTab: function (e) { | ||
this.active_settings_tab = $(e.target).attr('href'); | ||
}, | ||
|
||
// switch form | ||
switch_form: function () { | ||
this.is_form_switcher = (this.is_form_switcher) ? false : true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Simplify boolean toggling.
The static analysis tool warns of an unnecessary ternary. A more concise approach is:
-this.is_form_switcher = (this.is_form_switcher) ? false : true;
+this.is_form_switcher = !this.is_form_switcher;
📝 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.
this.is_form_switcher = (this.is_form_switcher) ? false : true; | |
this.is_form_switcher = !this.is_form_switcher; |
🧰 Tools
🪛 Biome (1.9.4)
[error] 636-636: 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)
if (panel === 'form-fields-v4-1') { | ||
this.$store.state.panel_sections = wpuf_form_builder.panel_sections; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use store mutations, not direct property assignments.
Setting this.$store.state.panel_sections
outside a mutation bypasses Vuex reactivity best practices. Wrap updates in either a mutation or an action to ensure consistent state changes.
<input | ||
@click="post_title_editing = !post_title_editing" | ||
v-model="post.post_title" | ||
type="text" | ||
name="post_title" | ||
:class="post_title_editing ? '' : '!wpuf-border-0'" | ||
class="wpuf-text-gray-900 placeholder:wpuf-text-gray-400 wpuf-font-medium wpuf-min-w-16 wpuf-max-w-40 wpuf-text-base wpuf-px-4 wpuf-py-3 wpuf-leading-none"> | ||
<i | ||
v-if="post_title_editing" | ||
@click="post_title_editing = !post_title_editing" | ||
class="fa fa-check !wpuf-leading-none hover:wpuf-cursor-pointer wpuf-ml-1 wpuf-text-base"></i> | ||
<div |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance form title editing accessibility.
The form title editing functionality lacks proper ARIA attributes and keyboard navigation support.
Apply these accessibility improvements:
<input
@click="post_title_editing = !post_title_editing"
v-model="post.post_title"
type="text"
name="post_title"
+ :aria-label="'Edit form title'"
+ :aria-expanded="post_title_editing"
+ @keydown.enter="post_title_editing = !post_title_editing"
:class="post_title_editing ? '' : '!wpuf-border-0'"
class="wpuf-text-gray-900 placeholder:wpuf-text-gray-400 wpuf-font-medium wpuf-min-w-16 wpuf-max-w-40 wpuf-text-base wpuf-px-4 wpuf-py-3 wpuf-leading-none">
📝 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.
<input | |
@click="post_title_editing = !post_title_editing" | |
v-model="post.post_title" | |
type="text" | |
name="post_title" | |
:class="post_title_editing ? '' : '!wpuf-border-0'" | |
class="wpuf-text-gray-900 placeholder:wpuf-text-gray-400 wpuf-font-medium wpuf-min-w-16 wpuf-max-w-40 wpuf-text-base wpuf-px-4 wpuf-py-3 wpuf-leading-none"> | |
<i | |
v-if="post_title_editing" | |
@click="post_title_editing = !post_title_editing" | |
class="fa fa-check !wpuf-leading-none hover:wpuf-cursor-pointer wpuf-ml-1 wpuf-text-base"></i> | |
<div | |
<input | |
@click="post_title_editing = !post_title_editing" | |
v-model="post.post_title" | |
type="text" | |
name="post_title" | |
:aria-label="'Edit form title'" | |
:aria-expanded="post_title_editing" | |
@keydown.enter="post_title_editing = !post_title_editing" | |
:class="post_title_editing ? '' : '!wpuf-border-0'" | |
class="wpuf-text-gray-900 placeholder:wpuf-text-gray-400 wpuf-font-medium wpuf-min-w-16 wpuf-max-w-40 wpuf-text-base wpuf-px-4 wpuf-py-3 wpuf-leading-none"> | |
<i | |
v-if="post_title_editing" | |
@click="post_title_editing = !post_title_editing" | |
class="fa fa-check !wpuf-leading-none hover:wpuf-cursor-pointer wpuf-ml-1 wpuf-text-base"></i> | |
<div |
<div class="wpuf-flex wpuf-items-center wpuf-mt-8"> | ||
<div class="wpuf-flex wpuf-bg-gray-100 wpuf-w-max wpuf-rounded-lg wpuf-p-2"> | ||
<a | ||
@click="active_tab = 'form-editor'" | ||
:class="active_tab === 'form-editor' ? '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-base 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 hover:wpuf-cursor-pointer"> | ||
<?php esc_html_e( 'Form Editor', 'wp-user-frontend' ); ?> | ||
</a> | ||
<a | ||
@click="active_tab = 'form-settings'" | ||
:class="active_tab === 'form-settings' ? '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-base 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 hover:wpuf-cursor-pointer"> | ||
<?php esc_html_e( 'Settings', 'wp-user-frontend' ); ?> | ||
</a> | ||
<?php do_action( "wpuf-form-builder-tabs-{$form_type}" ); ?> | ||
</div> | ||
</div> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance tab navigation accessibility.
The tab navigation needs proper ARIA attributes and keyboard support.
Apply these accessibility improvements:
-<div class="wpuf-flex wpuf-bg-gray-100 wpuf-w-max wpuf-rounded-lg wpuf-p-2">
+<div
+ class="wpuf-flex wpuf-bg-gray-100 wpuf-w-max wpuf-rounded-lg wpuf-p-2"
+ role="tablist"
+ aria-label="Form builder sections">
<a
@click="active_tab = 'form-editor'"
+ role="tab"
+ :aria-selected="active_tab === 'form-editor'"
+ :tabindex="active_tab === 'form-editor' ? 0 : -1"
+ @keydown.right="active_tab = 'form-settings'"
+ @keydown.left="active_tab = 'form-settings'"
:class="active_tab === 'form-editor' ? 'wpuf-bg-white wpuf-text-gray-800 wpuf-rounded-md wpuf-drop-shadow-sm' : ''"
class="wpuf-nav-tab">
📝 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.
<div class="wpuf-flex wpuf-items-center wpuf-mt-8"> | |
<div class="wpuf-flex wpuf-bg-gray-100 wpuf-w-max wpuf-rounded-lg wpuf-p-2"> | |
<a | |
@click="active_tab = 'form-editor'" | |
:class="active_tab === 'form-editor' ? '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-base 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 hover:wpuf-cursor-pointer"> | |
<?php esc_html_e( 'Form Editor', 'wp-user-frontend' ); ?> | |
</a> | |
<a | |
@click="active_tab = 'form-settings'" | |
:class="active_tab === 'form-settings' ? '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-base 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 hover:wpuf-cursor-pointer"> | |
<?php esc_html_e( 'Settings', 'wp-user-frontend' ); ?> | |
</a> | |
<?php do_action( "wpuf-form-builder-tabs-{$form_type}" ); ?> | |
</div> | |
</div> | |
</div> | |
<div class="wpuf-flex wpuf-items-center wpuf-mt-8"> | |
<div | |
class="wpuf-flex wpuf-bg-gray-100 wpuf-w-max wpuf-rounded-lg wpuf-p-2" | |
role="tablist" | |
aria-label="Form builder sections"> | |
<a | |
@click="active_tab = 'form-editor'" | |
role="tab" | |
:aria-selected="active_tab === 'form-editor'" | |
:tabindex="active_tab === 'form-editor' ? 0 : -1" | |
@keydown.right="active_tab = 'form-settings'" | |
@keydown.left="active_tab = 'form-settings'" | |
:class="active_tab === 'form-editor' ? '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-base 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 hover:wpuf-cursor-pointer"> | |
<?php esc_html_e( 'Form Editor', 'wp-user-frontend' ); ?> | |
</a> | |
<a | |
@click="active_tab = 'form-settings'" | |
:class="active_tab === 'form-settings' ? '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-base 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 hover:wpuf-cursor-pointer"> | |
<?php esc_html_e( 'Settings', 'wp-user-frontend' ); ?> | |
</a> | |
<?php do_action( "wpuf-form-builder-tabs-{$form_type}" ); ?> | |
</div> | |
</div> | |
</div> |
console.log('2'); | ||
settings_element.options = JSON.parse(data_raw); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove Debug Logging Statement (Console.log '2')
A similar debug log (console.log('2');
) is present in the init_textbox
branch for processing data from the element’s attribute. Please remove this statement to keep the production console clean.
- console.log('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.
console.log('2'); | |
settings_element.options = JSON.parse(data_raw); | |
settings_element.options = JSON.parse(data_raw); |
console.log('3'); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove Debug Logging Statement (Console.log '3')
There is an unexpected console.log('3');
in the addOption
helper function. This logging should be removed to prevent cluttering the console in production.
- console.log('3');
📝 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.
console.log('3'); | |
return; | |
return; |
console.log('1'); | ||
var value = $.trim($input.val() || ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove Debug Logging Statement (Console.log '1')
A debug statement (console.log('1');
) was added in the initialization logic for textbox options. This appears to be leftover debugging code that should be removed before production to avoid unwanted console output.
- console.log('1');
📝 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.
console.log('1'); | |
var value = $.trim($input.val() || ''); | |
var value = $.trim($input.val() || ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (7)
admin/form-builder/assets/js/form-builder.js (3)
708-725
: Consider extracting Tailwind CSS classes into a configuration object.The
setting_class_names
method contains hardcoded Tailwind CSS classes. Consider extracting these into a configuration object for better maintainability and reusability.const FIELD_CLASSES = { upload_btn: 'file-selector wpuf-rounded-md wpuf-btn-secondary', radio: 'wpuf-mx-3 !wpuf-my-0 wpuf-block wpuf-text-base wpuf-font-medium wpuf-text-gray-900 checked:focus:!wpuf-bg-primary checked:hover:!wpuf-bg-primary checked:before:!wpuf-bg-white checked:!wpuf-bg-primary', // ... other field types }; setting_class_names(field_type) { return FIELD_CLASSES[field_type] || FIELD_CLASSES.default; }
490-499
: Consider reducing the setTimeout delay for selectize initialization.The watch property for
active_settings_tab
uses a 100ms delay to initialize selectize. Consider reducing this delay or using Vue'snextTick
for better performance:-setTimeout(function() { - $('.wpuf-settings-container select').selectize({ - plugins: ['remove_button'], - }); -}, 100); +Vue.nextTick(function() { + $('.wpuf-settings-container select').selectize({ + plugins: ['remove_button'], + }); +});
1015-1111
: Consider modernizing the Form Dependency Handler.The
FormDependencyHandler
class is well-structured but heavily relies on jQuery. Consider these improvements:
- Use modern DOM APIs instead of jQuery
- Add error handling for missing elements
- Consider using a pub/sub pattern for dependency updates
Example modernization:
class FormDependencyHandler { // ... existing constructor and init ... attachFieldListener(fieldId) { const field = document.getElementById(fieldId); if (!field) { console.warn(`Field ${fieldId} not found`); return; } const fieldType = field.type || field.tagName.toLowerCase(); field.addEventListener('change', () => this.checkAllDependencies()); } showField(fieldId) { const field = document.getElementById(fieldId); if (!field) return; const container = field.closest('.wpuf-input-container'); if (container) { container.style.display = 'block'; container.style.opacity = '0'; requestAnimationFrame(() => { container.style.transition = 'opacity 200ms'; container.style.opacity = '1'; }); } } }assets/js/wpuf-form-builder.js (4)
519-590
: Refactor duplicate clipboard initialization code.The clipboard initialization and tooltip handling code is duplicated between the post form and non-post form branches. This violates the DRY principle and makes maintenance harder.
Consider extracting the common clipboard logic into a separate method:
+ methods: { + initializeClipboard: function(clipboard, trigger) { + var self = this; + clipboard.on('success', function(e) { + $(e.trigger) + .attr('data-original-title', 'Shortcode copied!') + .tooltip('show'); + + self.shortcodeCopied = true; + + setTimeout(function() { + $(e.trigger).tooltip('hide') + .attr('data-original-title', self.i18n.copy_shortcode); + self.shortcodeCopied = false; + }, 1000); + + e.clearSelection(); + }); + } + } mounted: function() { var clipboard = new window.Clipboard('.form-id'); var settings_tabs = $('#wpuf-form-builder-settings-tabs .nav-tab'); var self = this; $(".form-id").tooltip(); if (this.is_post_form) { settings_tabs.each(function() { $(this).bind('click', self.setActiveSettingsTab); }); - clipboard.on('success', function(e) {...}); // Remove duplicate code + this.initializeClipboard(clipboard); } else { // ... other code ... - clipboard.on('success', function(e) {...}); // Remove duplicate code + this.initializeClipboard(clipboard); } }
1015-1111
: Enhance FormDependencyHandler with error handling and performance optimizations.The
FormDependencyHandler
class could benefit from:
- Error handling for missing fields
- Debouncing for change event handlers
- Caching of jQuery selectors
Consider these improvements:
class FormDependencyHandler { + constructor(dependencies) { + this.dependencies = dependencies; + this.fieldCache = new Map(); + this.init(); + } + getField(fieldId) { + if (!this.fieldCache.has(fieldId)) { + const field = $(`#${fieldId}`); + if (field.length === 0) { + console.warn(`Field ${fieldId} not found`); + return null; + } + this.fieldCache.set(fieldId, field); + } + return this.fieldCache.get(fieldId); + } + attachFieldListener(fieldId) { + const field = this.getField(fieldId); + if (!field) return; + + const fieldType = field.attr('type') || field.prop('tagName').toLowerCase(); + const debouncedCheck = _.debounce(() => this.checkAllDependencies(), 250); + + if (fieldType === 'checkbox' || fieldType === 'select' || fieldType === 'radio') { + field.on('change', debouncedCheck); + } + }
635-637
: Simplify boolean toggle logic.The ternary operator is unnecessary for toggling a boolean value.
Apply this diff to simplify the code:
switch_form: function () { - this.is_form_switcher = (this.is_form_switcher) ? false : true; + this.is_form_switcher = !this.is_form_switcher; }🧰 Tools
🪛 Biome (1.9.4)
[error] 636-636: 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)
1126-1161
: Simplify category selector logic using template literals.The string concatenation for category selector could be simplified using template literals.
Apply this diff to improve readability:
function populate_default_categories(obj) { var post_type = $(obj).val(); + const defaultCategorySelector = post_type === 'post' + ? 'select#default_category' + : `select#default_${post_type}_cat`; - const default_category = 'select#default_category'; - let default_category_name = default_category; - if (post_type !== 'post') { - default_category_name = 'select#default_' + post_type + '_cat'; - }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
admin/form-builder/assets/js/form-builder.js
(14 hunks)assets/js/wpuf-form-builder.js
(14 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
admin/form-builder/assets/js/form-builder.js
[error] 636-636: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
assets/js/wpuf-form-builder.js
[error] 636-636: 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)
🔇 Additional comments (4)
admin/form-builder/assets/js/form-builder.js (2)
396-403
: LGTM: New panel section mutations.The new mutations
set_panel_sections
andset_default_panel_sections
are well-implemented and provide good flexibility for managing panel sections.
635-637
: Simplify boolean toggling.The static analysis tool warns of an unnecessary ternary. A more concise approach is:
-this.is_form_switcher = (this.is_form_switcher) ? false : true; +this.is_form_switcher = !this.is_form_switcher;🧰 Tools
🪛 Biome (1.9.4)
[error] 636-636: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with(lint/complexity/noUselessTernary)
assets/js/wpuf-form-builder.js (2)
93-96
: Add array bounds check before accessing field[0].The code attempts to access
field[0]
without verifying the array length, which could lead to undefined behavior if the field array is empty.Apply this diff to add a safety check:
open_field_settings: function ( state, field_id ) { var field = state.form_fields.filter( function ( item ) { return parseInt( field_id ) === parseInt( item.id ); } ); + if (!field.length) { + return; + }
396-398
: 🛠️ Refactor suggestionUse Vue.set for reactive state updates.
Direct state mutation bypasses Vue's reactivity system. Use
Vue.set
to ensure proper reactivity.Apply this diff to fix the reactivity issue:
set_panel_sections: function ( state, sections ) { - state.panel_sections = sections; + Vue.set(state, 'panel_sections', sections); }Likely an incorrect or invalid review comment.
is_older_form: wpuf_form_builder.is_older_form, | ||
is_post_form: wpuf_form_builder.is_older_form && wpuf_form_builder.post.post_type === 'wpuf_forms', | ||
current_panel: wpuf_form_builder.is_older_form && wpuf_form_builder.post.post_type !== 'wpuf_forms' ? 'form-fields' : 'form-fields-v4-1', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix potential bug in is_post_form
state property.
The is_post_form
state property has a potential bug as it's using is_older_form
instead of post.post_type
:
-is_post_form: wpuf_form_builder.is_older_form && wpuf_form_builder.post.post_type === 'wpuf_forms',
+is_post_form: wpuf_form_builder.post.post_type === 'wpuf_forms',
📝 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.
is_older_form: wpuf_form_builder.is_older_form, | |
is_post_form: wpuf_form_builder.is_older_form && wpuf_form_builder.post.post_type === 'wpuf_forms', | |
current_panel: wpuf_form_builder.is_older_form && wpuf_form_builder.post.post_type !== 'wpuf_forms' ? 'form-fields' : 'form-fields-v4-1', | |
is_older_form: wpuf_form_builder.is_older_form, | |
is_post_form: wpuf_form_builder.post.post_type === 'wpuf_forms', | |
current_panel: wpuf_form_builder.is_older_form && wpuf_form_builder.post.post_type !== 'wpuf_forms' ? 'form-fields' : 'form-fields-v4-1', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
wpuf-functions.php (1)
4821-4842
: Add PHPDoc blocks for better documentationThe new utility functions would benefit from proper PHPDoc blocks documenting:
- Parameters and return types
- Example usage
- Since version tag
Add PHPDoc blocks like this:
+/** + * Get the URL for the pro version crown icon + * + * @since x.x.x + * + * @return string URL to the crown icon asset + */ function wpuf_get_pro_icon() { +/** + * Check if the pro version of the plugin is active + * + * @since x.x.x + * + * @return bool True if pro version is active + */ function wpuf_is_pro_active() {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
wpuf-functions.php
(4 hunks)
🔇 Additional comments (1)
wpuf-functions.php (1)
4844-5399
: Well structured implementation with good organizationThe new form builder settings functions are well implemented with:
- Clear separation of concerns between titles and contents
- Comprehensive settings covering all aspects
- Good use of filters for extensibility
- Semantic SVG icons for visual elements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (2)
assets/js/wpuf-form-builder.js (1)
91-106
: 🛠️ Refactor suggestionPotential race condition in field settings update.
The setTimeout delay in open_field_settings could lead to race conditions if multiple fields are opened in quick succession.
Consider using Vue's nextTick instead:
-setTimeout(function () { - state.editing_field_id = field[0].id; -}, 400); +Vue.nextTick(function () { + state.editing_field_id = field[0].id; +});src/css/admin/form-builder.css (1)
219-222
:⚠️ Potential issueMissing Closing Curly Bracket in CSS Block
The rule for.wpuf-field-sizing-content
(lines 219-221) is missing a closing curly bracket (}
). This will cause syntax errors and unexpected behaviors in CSS parsing. Additionally, verify whether the propertyfield-sizing
is intentional or if it should be a standard property likebox-sizing
.Proposed fix:
- .wpuf-field-sizing-content { - field-sizing: content; - } + .wpuf-field-sizing-content { + field-sizing: content; + }🧰 Tools
🪛 Biome (1.9.4)
[error] 221-221: expected
}
but instead the file endsthe file ends here
(parse)
🧹 Nitpick comments (5)
admin/form-builder/assets/js/form-builder.js (1)
959-1058
: Add error handling to FormDependencyHandler.The FormDependencyHandler class is well-structured but could benefit from improved error handling:
- Add try-catch blocks for DOM operations
- Add null checks for field elements
- Handle edge cases when dependencies are misconfigured
Example implementation:
checkFieldDependencies(fieldId) { + try { const fieldConfig = this.dependencies.fields[fieldId]; + if (!fieldConfig) { + console.warn(`No configuration found for field: ${fieldId}`); + return; + } const shouldShow = this.shouldFieldBeVisible(fieldConfig.dependsOn); if (shouldShow) { this.showField(fieldId); this.attachSelectize(fieldId); } else { this.hideField(fieldId); } + } catch (error) { + console.error(`Error handling dependencies for field ${fieldId}:`, error); + } }assets/js/wpuf-form-builder.js (3)
652-669
: Refactor CSS class management.The setting_class_names method contains hardcoded Tailwind CSS classes. This makes maintenance difficult and could lead to inconsistencies.
Consider extracting these classes to a configuration object:
+const FIELD_TYPE_CLASSES = { + upload_btn: 'file-selector wpuf-rounded-md wpuf-btn-secondary', + radio: 'wpuf-mx-3 !wpuf-my-0 wpuf-block wpuf-text-base wpuf-font-medium wpuf-text-gray-900 checked:focus:!wpuf-bg-primary checked:hover:!wpuf-bg-primary checked:before:!wpuf-bg-white checked:!wpuf-bg-primary', + checkbox: 'wpuf-h-4 wpuf-w-4 wpuf-rounded wpuf-border-gray-300 !wpuf-mt-0.5 checked:focus:!wpuf-bg-primary checked:hover:wpuf-bg-primary checked:!wpuf-bg-primary before:!wpuf-content-none', + dropdown: 'wpuf-block wpuf-w-full wpuf-min-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 wpuf-border !wpuf-border-gray-300', + default: 'wpuf-block wpuf-min-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full' +}; setting_class_names: function(field_type) { - switch (field_type) { - case 'upload_btn': - return 'file-selector wpuf-rounded-md wpuf-btn-secondary'; - // ... other cases - } + return FIELD_TYPE_CLASSES[field_type] || FIELD_TYPE_CLASSES.default; }
713-931
: Improve dependency configuration management.The dependencies configuration is tightly coupled and difficult to maintain. Consider extracting it to a separate configuration file.
Create a new file
form-dependencies.config.js
:// form-dependencies.config.js export const formDependencies = { fields: { message: { type: 'textarea', dependsOn: [{ field: 'redirect_to', value: 'same' }] }, // ... other fields } };Then import and use it:
-const dependencies = { - fields: { - // ... large configuration object - } -}; +import { formDependencies } from './form-dependencies.config.js'; +const dependencies = formDependencies;
580-581
: Simplify boolean toggle.The ternary operator is unnecessary for toggling a boolean value.
-this.is_form_switcher = (this.is_form_switcher) ? false : true; +this.is_form_switcher = !this.is_form_switcher;🧰 Tools
🪛 Biome (1.9.4)
[error] 580-580: 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)
src/css/admin/form-builder.css (1)
66-71
: Review Background Property Ordering
Within the.wpuf-pattern-1
block, bothbackground-color: #ffffff;
(line 68) and the shorthandbackground: repeating-linear-gradient(...)
(line 70) are declared. Note that the shorthand property on line 70 will override the earlierbackground-color
. If a fallback color is needed for unsupported browsers, consider placing thebackground-color
declaration after the shorthand or merging the styles if possible. Please verify that this behavior is intentional.🧰 Tools
🪛 Biome (1.9.4)
[error] 70-70: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
admin/form-builder/assets/js/form-builder.js
(14 hunks)admin/form-builder/views/form-builder-v4.1.php
(1 hunks)assets/js/wpuf-form-builder.js
(14 hunks)src/css/admin/form-builder.css
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- admin/form-builder/views/form-builder-v4.1.php
🧰 Additional context used
🪛 Biome (1.9.4)
src/css/admin/form-builder.css
[error] 221-221: expected }
but instead the file ends
the file ends here
(parse)
[error] 70-70: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
admin/form-builder/assets/js/form-builder.js
[error] 580-580: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
assets/js/wpuf-form-builder.js
[error] 580-580: 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)
🔇 Additional comments (7)
admin/form-builder/assets/js/form-builder.js (3)
580-580
: Simplify boolean toggling.The static analysis tool warns of an unnecessary ternary. A more concise approach is:
-this.is_form_switcher = (this.is_form_switcher) ? false : true; +this.is_form_switcher = !this.is_form_switcher;🧰 Tools
🪛 Biome (1.9.4)
[error] 580-580: 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)
71-73
: LGTM! Good backward compatibility.The panel reset logic correctly handles both the old 'form-fields' and new 'form-fields-v4-1' panel names.
44-44
:❓ Verification inconclusive
Verify the impact of panel version change.
The default panel has been updated to use the new v4-1 version. Ensure that all components and features are compatible with this change.
🏁 Script executed:
#!/bin/bash # Search for components that might still reference the old panel name rg -A 5 "'form-fields'"Length of output: 2713
Action: Review Panel Version Transition Compatibility
The default panel has been updated to
'form-fields-v4-1'
and the JavaScript now correctly handles both'form-fields'
and'form-fields-v4-1'
in its conditional logic. However, note the following:
JavaScript Logic (admin/form-builder/assets/js/form-builder.js):
The if-condition:if ('form-fields' === panel || 'form-fields-v4-1' === panel) { state.editing_field_id = 0; }correctly checks for both values, which helps maintain backward compatibility.
View Files (e.g., admin/form-builder/views/form-builder.php):
The views still reference'form-fields'
in both the active tab class and in the click handler (i.e.,@click.prevent="set_current_panel('form-fields')"
). Verify that this discrepancy is intentional and that the UI correctly highlights the intended panel when the default is now'form-fields-v4-1'
.Please confirm that the design intends for the view components to continue using
'form-fields'
while the JavaScript defaults to'form-fields-v4-1'
(with support for both strings). If the views should be updated for consistency with the new default, please adjust accordingly.assets/js/wpuf-form-builder.js (1)
585-587
: Use store mutations, not direct property assignments.Direct state mutation bypasses Vue's reactivity system and can lead to inconsistent state. Use mutations to update the state.
Replace the direct state mutation with a mutation call:
-this.$store.state.panel_sections = wpuf_form_builder.panel_sections; +this.$store.commit('set_default_panel_sections');src/css/admin/form-builder.css (3)
1-3
: Tailwind Directives Initialization
The use of@tailwind base;
,@tailwind components;
, and@tailwind utilities;
is correct and sets up Tailwind CSS properly.
5-33
: Component Layer Styles - Looks Good
The@layer components
block correctly defines styles for various components such as buttons, tooltips, checkboxes, and panels using the Tailwind@apply
directive. No issues noted regarding naming or application of utilities.
35-51
: Utilities Layer Definitions
The utility classes defined in the@layer utilities
block are well-structured and clear. The transition properties and scaling effects are implemented appropriately.
$('select#post_type').on('change', function() { | ||
populate_default_categories(this); | ||
}); | ||
|
||
function populate_default_categories(obj) { | ||
var post_type = $( obj ).val(); | ||
wp.ajax.send('wpuf_form_setting_post', { | ||
data: { | ||
post_type: post_type, | ||
wpuf_form_builder_setting_nonce: wpuf_form_builder.nonce | ||
}, | ||
success: function (response) { | ||
$('.wpuf_settings_taxonomy').remove(); | ||
$('.wpuf-post-fromat').after(response.data); | ||
const default_category = 'select#default_category'; | ||
let default_category_name = default_category; | ||
|
||
if ( post_type !== 'post' ) { | ||
default_category_name = 'select#default_' + post_type + '_cat'; | ||
} | ||
|
||
const value = $(default_category_name).data('value'); | ||
|
||
$(default_category).parent('.wpuf-my-4.wpuf-input-container').remove(); | ||
$('select#post_type').parent('.wpuf-my-4.wpuf-input-container').after(response.data); | ||
|
||
if (value && ( typeof value === 'string' )) { | ||
$(default_category).val(value.split(",")); | ||
} else { | ||
$(default_category).val(value); | ||
} | ||
|
||
$(default_category).selectize({ | ||
plugins: ['remove_button'], | ||
}); | ||
|
||
}, | ||
error: function ( error ) { | ||
console.log(error); | ||
} | ||
}); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve error handling in AJAX call.
The error handling for the category population AJAX call only logs to console. Consider:
- Adding user feedback for failures
- Implementing retry logic
- Restoring previous state on failure
function populate_default_categories(obj) {
var post_type = $(obj).val();
+ const originalValue = $(obj).data('original-value');
wp.ajax.send('wpuf_form_setting_post', {
data: {
post_type: post_type,
wpuf_form_builder_setting_nonce: wpuf_form_builder.nonce
},
success: function (response) {
// ... existing success handling ...
},
error: function (error) {
- console.log(error);
+ // Restore previous value
+ $(obj).val(originalValue);
+
+ // Show user feedback
+ toastr.error(wpuf_form_builder.i18n.category_load_error || 'Failed to load categories');
+
+ // Log for debugging
+ console.error('Category loading failed:', error);
}
});
}
📝 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.
$('select#post_type').on('change', function() { | |
populate_default_categories(this); | |
}); | |
function populate_default_categories(obj) { | |
var post_type = $( obj ).val(); | |
wp.ajax.send('wpuf_form_setting_post', { | |
data: { | |
post_type: post_type, | |
wpuf_form_builder_setting_nonce: wpuf_form_builder.nonce | |
}, | |
success: function (response) { | |
$('.wpuf_settings_taxonomy').remove(); | |
$('.wpuf-post-fromat').after(response.data); | |
const default_category = 'select#default_category'; | |
let default_category_name = default_category; | |
if ( post_type !== 'post' ) { | |
default_category_name = 'select#default_' + post_type + '_cat'; | |
} | |
const value = $(default_category_name).data('value'); | |
$(default_category).parent('.wpuf-my-4.wpuf-input-container').remove(); | |
$('select#post_type').parent('.wpuf-my-4.wpuf-input-container').after(response.data); | |
if (value && ( typeof value === 'string' )) { | |
$(default_category).val(value.split(",")); | |
} else { | |
$(default_category).val(value); | |
} | |
$(default_category).selectize({ | |
plugins: ['remove_button'], | |
}); | |
}, | |
error: function ( error ) { | |
console.log(error); | |
} | |
}); | |
}); | |
} | |
$('select#post_type').on('change', function() { | |
populate_default_categories(this); | |
}); | |
function populate_default_categories(obj) { | |
var post_type = $(obj).val(); | |
const originalValue = $(obj).data('original-value'); | |
wp.ajax.send('wpuf_form_setting_post', { | |
data: { | |
post_type: post_type, | |
wpuf_form_builder_setting_nonce: wpuf_form_builder.nonce | |
}, | |
success: function (response) { | |
const default_category = 'select#default_category'; | |
let default_category_name = default_category; | |
if (post_type !== 'post') { | |
default_category_name = 'select#default_' + post_type + '_cat'; | |
} | |
const value = $(default_category_name).data('value'); | |
$(default_category).parent('.wpuf-my-4.wpuf-input-container').remove(); | |
$('select#post_type').parent('.wpuf-my-4.wpuf-input-container').after(response.data); | |
if (value && (typeof value === 'string')) { | |
$(default_category).val(value.split(",")); | |
} else { | |
$(default_category).val(value); | |
} | |
$(default_category).selectize({ | |
plugins: ['remove_button'], | |
}); | |
}, | |
error: function (error) { | |
// Restore previous value | |
$(obj).val(originalValue); | |
// Show user feedback | |
toastr.error(wpuf_form_builder.i18n.category_load_error || 'Failed to load categories'); | |
// Log for debugging | |
console.error('Category loading failed:', error); | |
} | |
}); | |
} |
$('#wpuf-form-builder').on('click', '#wpuf-toggle-field-options, #wpuf-toggle-show-form, .field-buttons .fa-pencil, .ui-draggable-handle', function() { | ||
$('#wpuf-toggle-field-options').toggleClass('hide'); | ||
$('#wpuf-toggle-show-form').toggleClass('show'); | ||
$('#builder-form-fields').toggleClass('show'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Migrate from jQuery to Vue patterns.
Using jQuery for DOM manipulation alongside Vue can lead to inconsistencies with Vue's virtual DOM management.
Consider using Vue's event handling and class bindings:
-$('#wpuf-form-builder').on('click', '#wpuf-toggle-field-options, #wpuf-toggle-show-form, .field-buttons .fa-pencil, .ui-draggable-handle', function() {
- $('#wpuf-toggle-field-options').toggleClass('hide');
- $('#wpuf-toggle-show-form').toggleClass('show');
- $('#builder-form-fields').toggleClass('show');
-});
+<template>
+ <div @click="toggleFieldOptions">
+ <div :class="{ 'hide': isFieldOptionsHidden }">...</div>
+ <div :class="{ 'show': isFormShown }">...</div>
+ <div :class="{ 'show': isBuilderFieldsShown }">...</div>
+ </div>
+</template>
+
+<script>
+methods: {
+ toggleFieldOptions() {
+ this.isFieldOptionsHidden = !this.isFieldOptionsHidden;
+ this.isFormShown = !this.isFormShown;
+ this.isBuilderFieldsShown = !this.isBuilderFieldsShown;
+ }
+}
+</script>
Committable suggestion skipped: line range outside the PR's diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
♻️ Duplicate comments (7)
assets/js/wpuf-form-builder.js (1)
585-587
: 🛠️ Refactor suggestionUse store mutations instead of direct state modification.
Setting
this.$store.state.panel_sections
directly bypasses Vuex's reactivity system and state management patterns. This can lead to inconsistent state and make debugging more difficult.if (panel === 'form-fields-v4-1') { - this.$store.state.panel_sections = wpuf_form_builder.panel_sections; + this.$store.commit('set_default_panel_sections'); }admin/form-builder/views/form-builder-v4.1.php (2)
12-18
: 🛠️ Refactor suggestionEnhance form title editing accessibility.
The form title editing input lacks ARIA attributes for better accessibility.
Apply these accessibility improvements:
<input @click="post_title_editing = !post_title_editing" v-model="post.post_title" type="text" name="post_title" + aria-label="Edit form title" + :aria-expanded="post_title_editing" + @keydown.enter="post_title_editing = !post_title_editing" :class="post_title_editing ? '' : '!wpuf-border-0'" class="wpuf-text-gray-900 wpuf-text-base wpuf-field-sizing-content">
129-146
: 🛠️ Refactor suggestionEnhance tab navigation accessibility.
The tab navigation needs proper ARIA attributes and keyboard support.
Apply these accessibility improvements:
-<div class="wpuf-flex wpuf-bg-gray-100 wpuf-w-max wpuf-rounded-lg wpuf-p-2"> +<div + class="wpuf-flex wpuf-bg-gray-100 wpuf-w-max wpuf-rounded-lg wpuf-p-2" + role="tablist" + aria-label="Form builder sections"> <a @click="active_tab = 'form-editor'" + role="tab" + :aria-selected="active_tab === 'form-editor'" + :tabindex="active_tab === 'form-editor' ? 0 : -1" + @keydown.right="active_tab = 'form-settings'" + @keydown.left="active_tab = 'form-settings'" :class="active_tab === 'form-editor' ? 'wpuf-bg-white wpuf-text-gray-800 wpuf-rounded-md wpuf-drop-shadow-sm' : ''" class="wpuf-nav-tab">admin/form-builder/assets/js/components/field-select/template.php (1)
8-30
: 🛠️ Refactor suggestionEnhance accessibility of custom dropdown.
The custom dropdown implementation lacks essential accessibility features for keyboard navigation and screen reader support.
Apply these accessibility enhancements:
<div class="option-fields-section wpuf-relative"> <p @click="showOptions = !showOptions" + @keydown.enter="showOptions = !showOptions" + @keydown.space.prevent="showOptions = !showOptions" + @keydown.up.prevent="navigateOptions('up')" + @keydown.down.prevent="navigateOptions('down')" + role="combobox" + :aria-expanded="showOptions" + :aria-controls="'select-options-' + option_field.id" + tabindex="0" class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-min-w-full wpuf-rounded-md wpuf-py-1 wpuf-px-2 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full hover:wpuf-cursor-pointer" > {{ selectedOption }} <i :class="showOptions ? 'fa-angle-up' : 'fa-angle-down'" class="fa" + aria-hidden="true" ></i> </p> <div v-if="showOptions" + :id="'select-options-' + option_field.id" + role="listbox" class="wpuf-absolute wpuf-bg-white wpuf-border wpuf-border-gray-300 wpuf-rounded-lg wpuf-w-full wpuf-z-10 wpuf--mt-4"> <ul> <li v-for="(option, key) in option_field.options" @click="[value = key, showOptions = false, selectedOption = option]" + @keydown.enter="[value = key, showOptions = false, selectedOption = option]" + role="option" + :aria-selected="value === key" + tabindex="0" :value="key" class="wpuf-text-sm wpuf-color-gray-900 wpuf-py-2 wpuf-px-4 hover:wpuf-cursor-pointer hover:wpuf-bg-gray-100">{{ option }}</li> </ul> </div> </div>You'll also need to add keyboard navigation methods to the component:
methods: { navigateOptions(direction) { if (!this.showOptions) { this.showOptions = true; return; } const options = Object.keys(this.option_field.options); const currentIndex = options.indexOf(this.value); let newIndex; if (direction === 'up') { newIndex = currentIndex > 0 ? currentIndex - 1 : options.length - 1; } else { newIndex = currentIndex < options.length - 1 ? currentIndex + 1 : 0; } this.value = options[newIndex]; this.selectedOption = this.option_field.options[options[newIndex]]; } }admin/form-builder/assets/js/components/builder-stage-v4-1/template.php (2)
2-6
: 🛠️ Refactor suggestionEnhance empty state accessibility.
The empty state section needs accessibility improvements:
- The image lacks meaningful alt text
- The heading and paragraph contain duplicate text
Apply this diff to improve accessibility:
-<img src="<?php echo WPUF_ASSET_URI . '/images/form-blank-state.svg'; ?>" alt=""> +<img src="<?php echo WPUF_ASSET_URI . '/images/form-blank-state.svg'; ?>" alt="Empty form builder state"> -<p class="wpuf-text-sm wpuf-text-gray-500"><?php esc_html_e( 'Add fields and build your desired form', 'wp-user-frontend' ); ?></p> +<p class="wpuf-text-sm wpuf-text-gray-500"><?php esc_html_e( 'Start by dragging fields from the sidebar', 'wp-user-frontend' ); ?></p>
125-169
:⚠️ Potential issueEnhance hidden fields section security.
The hidden fields section exposes sensitive data in the UI without sanitization.
Apply this security enhancement:
-<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 }} +<strong><?php esc_html_e( 'key', 'wp-user-frontend' ); ?></strong>: {{ sanitize(field.name) }} | +<strong><?php esc_html_e( 'value', 'wp-user-frontend' ); ?></strong>: {{ maskSensitiveData(field.meta_value) }}Add these methods to your component:
methods: { sanitize(str) { if (!str) return ''; return String(str) .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); }, maskSensitiveData(value) { // Check if value might contain sensitive data if (typeof value !== 'string') { return value; } // If it's a potentially sensitive value like API key or password if (/key|pass|secret|token|auth/i.test(this.field.name)) { if (value.length > 4) { return value.substr(0, 2) + '•'.repeat(value.length - 4) + value.substr(-2); } return '•'.repeat(value.length); } return this.sanitize(value); } }assets/js-templates/form-components.php (1)
221-223
:⚠️ Potential issueAdd data sanitization and masking for hidden fields.
Hidden field values may contain sensitive data and should be properly sanitized and masked.
Apply this security fix:
- <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 }} + <strong><?php esc_html_e( 'key', 'wp-user-frontend' ); ?></strong>: {{ sanitize(field.name) }} | + <strong><?php esc_html_e( 'value', 'wp-user-frontend' ); ?></strong>: {{ maskSensitiveData(field.meta_value) }}And add the sanitization and masking methods to your component.
🧹 Nitpick comments (11)
assets/js/wpuf-form-builder.js (2)
580-581
: Simplify conditional expression.The conditional can be simplified to directly toggle the boolean value without using a ternary operator.
- this.is_form_switcher = (this.is_form_switcher) ? false : true; + this.is_form_switcher = !this.is_form_switcher;🧰 Tools
🪛 Biome (1.9.4)
[error] 580-580: 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)
1057-1057
: Consider scope protection for the FormDependencyHandler class.Exposing the class directly to the global
window
object could lead to namespace collisions or unintended modifications. Consider using a module system or namespacing to better protect the class.- window.FormDependencyHandler = FormDependencyHandler; + window.wpuf = window.wpuf || {}; + window.wpuf.FormDependencyHandler = FormDependencyHandler;src/css/admin/form-builder.css (1)
168-202
: Standardize color usage for range inputs.The range input styling uses hardcoded "green" color values in multiple places, which doesn't match the design system used elsewhere in the file (Tailwind's color system with emerald tones).
Consider replacing the hardcoded "green" values with Tailwind color variables or custom properties:
- background: green; + background: #059669; /* matches line 74's color for consistency */Apply similar changes to all instances of "green" in this section.
admin/form-builder/views/form-builder-v4.1.php (2)
54-54
: Use WordPress sanitization functions for GET parameters.While
intval()
provides basic sanitization, using WordPress functions would be more consistent with WordPress coding standards.Apply this change:
-$form_id = isset( $_GET['id'] ) ? intval( wp_unslash( $_GET['id'] ) ) : 0; +$form_id = isset( $_GET['id'] ) ? absint( sanitize_text_field( wp_unslash( $_GET['id'] ) ) ) : 0;
187-198
: Remove commented-out code.The file contains commented-out HTML/PHP that should be removed to improve code maintainability.
Remove the commented-out code in lines 187-198 if it's no longer needed.
admin/form-builder/assets/js/components/field-select/template.php (1)
2-6
: Add missing id attribute to the dropdown for proper label association.For proper accessibility, form controls should have IDs that match their labels' "for" attributes.
Add a unique ID to the dropdown container:
<div class="wpuf-flex"> <label v-if="option_field.title" class="!wpuf-mb-0"> + <span :id="'label-for-' + option_field.id"> {{ option_field.title }} <help-text v-if="option_field.help_text" :text="option_field.help_text"></help-text> + </span> </label> </div>Then reference this ID in your dropdown element using aria-labelledby:
<p @click="showOptions = !showOptions" + :aria-labelledby="'label-for-' + option_field.id" class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-min-w-full wpuf-rounded-md wpuf-py-1 wpuf-px-2 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full hover:wpuf-cursor-pointer" >
admin/form-builder/assets/js/components/builder-stage-v4-1/template.php (1)
39-50
: Add ARIA attributes to form field interaction layer.The overlay div that enables interaction with form fields lacks accessibility attributes.
Add proper ARIA attributes:
-<div class="wpuf-absolute wpuf-w-full wpuf-h-full wpuf-z-10"></div> +<div + class="wpuf-absolute wpuf-w-full wpuf-h-full wpuf-z-10" + role="button" + :aria-label="'Edit ' + field.label" + tabindex="0" + @keydown.enter="open_field_settings(field.id)" +></div>assets/js-templates/form-components.php (4)
88-91
: Fix duplicate text in empty state message.The heading and paragraph in the empty state contain the exact same text, which is redundant for users and screen readers.
Apply this change:
<h2 class="wpuf-text-lg wpuf-text-gray-800 wpuf-mt-8 wpuf-mb-2"><?php esc_html_e( 'Add fields and build your desired form', 'wp-user-frontend' ); ?></h2> - <p class="wpuf-text-sm wpuf-text-gray-500"><?php esc_html_e( 'Add fields and build your desired form', 'wp-user-frontend' ); ?></p> + <p class="wpuf-text-sm wpuf-text-gray-500"><?php esc_html_e( 'Drag form fields from the right sidebar to this area', 'wp-user-frontend' ); ?></p>
1046-1050
: Enhance search input accessibility.The search field lacks a proper label, which hinders screen reader users.
Improve the accessibility of the search field:
<div class="wpuf-px-6"> <div class="wpuf-flex wpuf-rounded-lg wpuf-bg-white wpuf-outline wpuf--outline-1 wpuf--outline-offset-1 wpuf-outline-gray-300 wpuf-border wpuf-border-gray-200 wpuf-shadow wpuf-mb-8"> + <label for="wpuf-field-search" class="wpuf-sr-only"><?php esc_html_e( 'Search Field', 'wp-user-frontend' ); ?></label> <input type="text" name="search" - id="search" + id="wpuf-field-search" v-model="searched_fields" class="!wpuf-border-none !wpuf-rounded-[6px] 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-ring-transparent wpuf-shadow focus:!wpuf-shadow-none" placeholder="<?php esc_attr_e( 'Search Field', 'wp-user-frontend' ); ?>">Also, add a CSS class for screen-reader-only content if it doesn't exist:
.wpuf-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; }
1114-1118
: Add proper SVG accessibility for Pro feature indication.The Pro feature crown icon lacks proper accessibility attributes.
Enhance SVG accessibility:
<p class="wpuf-text-base wpuf-font-medium wpuf-text-gray-500 wpuf-m-0">{{ field_settings[field].title }}</p> </a> </div> - <img src="<?php esc_attr_e( WPUF_ASSET_URI . '/images/crown.svg' ); ?>" alt=""> + <img src="<?php esc_attr_e( WPUF_ASSET_URI . '/images/crown.svg' ); ?>" alt="Pro Feature" aria-label="<?php esc_attr_e( 'Premium Feature', 'wp-user-frontend' ); ?>" role="img">
1072-1077
: Add explicit accessible label to clear search button.The clear search button uses an icon without proper accessibility attributes.
Improve the clear button's accessibility:
<svg v-if="searched_fields" @click="searched_fields = ''" + aria-label="<?php esc_attr_e( 'Clear search', 'wp-user-frontend' ); ?>" + role="button" + tabindex="0" + @keydown.enter="searched_fields = ''" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="wpuf-size-5 hover:wpuf-cursor-pointer wpuf-transition-all">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
admin/form-builder/assets/js/components/builder-stage-v4-1/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/template.php
(1 hunks)admin/form-builder/assets/js/components/field-radio/template.php
(1 hunks)admin/form-builder/assets/js/components/field-select/template.php
(1 hunks)admin/form-builder/assets/js/components/field-text-meta/template.php
(1 hunks)admin/form-builder/assets/js/components/field-text/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-email_address/template.php
(1 hunks)admin/form-builder/assets/js/components/form-fields-v4-1/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_tags/template.php
(1 hunks)admin/form-builder/assets/js/components/form-post_title/template.php
(1 hunks)admin/form-builder/assets/js/form-builder.js
(14 hunks)admin/form-builder/assets/js/mixins/form-field.js
(3 hunks)admin/form-builder/assets/less/form-builder.less
(3 hunks)admin/form-builder/views/form-builder-v4.1.php
(1 hunks)assets/css/wpuf-form-builder.css
(3 hunks)assets/js-templates/form-components.php
(16 hunks)assets/js/wpuf-form-builder-mixins.js
(7 hunks)assets/js/wpuf-form-builder.js
(14 hunks)includes/Fields/Field_Contract.php
(2 hunks)src/css/admin/form-builder.css
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (15)
- admin/form-builder/assets/js/components/form-email_address/template.php
- admin/form-builder/assets/js/components/form-fields-v4-1/template.php
- admin/form-builder/assets/js/components/form-multiple_select/template.php
- admin/form-builder/assets/js/components/field-text/template.php
- admin/form-builder/assets/js/components/field-multiselect/template.php
- admin/form-builder/assets/js/components/form-post_title/template.php
- admin/form-builder/assets/js/components/field-option-data/template.php
- admin/form-builder/assets/js/components/form-checkbox_field/template.php
- admin/form-builder/assets/js/components/field-visibility/template.php
- includes/Fields/Field_Contract.php
- admin/form-builder/assets/js/components/field-text-meta/template.php
- admin/form-builder/assets/js/components/field-radio/template.php
- assets/css/wpuf-form-builder.css
- admin/form-builder/assets/js/components/form-post_tags/template.php
- admin/form-builder/assets/js/mixins/form-field.js
🧰 Additional context used
🪛 Biome (1.9.4)
src/css/admin/form-builder.css
[error] 221-221: expected }
but instead the file ends
the file ends here
(parse)
[error] 70-70: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
assets/js/wpuf-form-builder.js
[error] 580-580: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
admin/form-builder/assets/js/form-builder.js
[error] 580-580: 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)
🔇 Additional comments (33)
admin/form-builder/assets/less/form-builder.less (3)
269-269
: Color variable update for better consistencyThe background color for
.selectize-dropdown .active
has been changed from@wpBlue
to@wpufPrimary
. This aligns with what appears to be a new color system introduced in this PR.
677-678
: Enhanced dropzone styling with semantic colorsThe dropzone styling has been updated from faded yellow to a more modern green color scheme, improving visual clarity and providing better feedback for users when dragging elements.
-background-color: fade(@wpYellow, 30%); -border: 1px solid @wpYellow; +background-color: #f0fdf4; +border: 1px solid #4ade80;
1010-1010
: Modal height improvement for better usabilitySetting the form template modal to
100vh
ensures it always takes the full viewport height, providing more space for content and a more modern fullscreen experience.admin/form-builder/assets/js/form-builder.js (16)
44-44
: Updated current panel to new versionThe
current_panel
state property has been updated from 'form-fields' to 'form-fields-v4-1', which aligns with the form builder upgrade mentioned in the PR description.
71-73
: Improved panel reset logic with backward compatibilityThe logic for resetting the
editing_field_id
has been enhanced to support both old and new panel names, ensuring backward compatibility while the upgrade is in progress.
91-107
: Improved code formatting for better readabilityThe
open_field_settings
function has been reformatted with better spacing and indentation, making it more readable while maintaining the same functionality.
242-242
: Updated panel references in delete functionsBoth delete functions now correctly reference the new panel name 'form-fields-v4-1', ensuring consistent behavior when deleting fields.
Also applies to: 389-389
394-401
: Added panel section management methodsNew Vuex mutations have been added to manage panel sections more effectively:
set_panel_sections
- Updates panel sections with provided dataset_default_panel_sections
- Resets to default panel sections from configThese additions provide better control over the form builder UI panels.
420-429
: Enhanced data properties for improved UI state managementAdded new data properties:
isDirty
for tracking unsaved changesshortcodeCopied
for copy feedbacklogoUrl
for branding- Settings-related properties for better organization
These properties enable more sophisticated UI interactions and improved state management.
468-478
: Added computed properties for settings managementNew computed properties have been added to support the settings management system:
settings_titles
andsettings_items
for accessing settings datasection_exists
to check if a settings section existsThese properties make settings access more efficient and Vue-reactive.
488-497
: Added watcher for settings tab changesA new watcher for
active_settings_tab
initializes selectize dropdowns when the settings tab changes, ensuring dynamic UI elements are properly initialized.
503-508
: Improved initialization of select dropdownsAdded initialization of selectize for all dropdowns in the settings container, enhancing the UI with searchable, user-friendly dropdown controls.
580-580
: Simplify boolean toggling.The static analysis tool correctly flags an unnecessary ternary operator. A more concise approach would improve readability.
-this.is_form_switcher = (this.is_form_switcher) ? false : true; +this.is_form_switcher = !this.is_form_switcher;🧰 Tools
🪛 Biome (1.9.4)
[error] 580-580: 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)
652-669
: Added utility method for consistent field stylingThe
setting_class_names
method provides a centralized way to apply consistent CSS classes to form fields based on their type. This improves UI consistency and simplifies styling management.
671-678
: Added method for managing settings navigationThe
switch_settings_menu
method handles settings menu navigation, updating both the active tab and title. This centralizes navigation logic and ensures UI state consistency.
680-682
: Added method for handling pictorial radio settingsThe
switch_form_settings_pic_radio_item
method provides a dedicated handler for pictorial radio settings, making the codebase more organized and maintainable.
713-932
: Added comprehensive form field dependency configurationA detailed dependency configuration object has been added that defines relationships between form fields, specifying which fields should be shown or hidden based on values of other fields.
This structured approach improves maintainability and makes complex form interactions more manageable.
959-1057
: Added FormDependencyHandler class for field visibility managementA new
FormDependencyHandler
class has been implemented that:
- Initializes dependencies between form fields
- Handles field visibility based on configured conditions
- Manages listeners for dependency-triggering fields
- Provides methods for showing/hiding fields based on dependencies
This OOP approach is a significant improvement for managing complex form field relationships.
1066-1105
: Improved category population logicThe
populate_default_categories
function has been enhanced with better handling of post types and default category selection. However, the error handling could be improved.error: function ( error ) { - console.log(error); + console.error('Failed to load categories:', error); + // Show user-friendly error message + toastr.error(wpuf_form_builder.i18n.category_load_error || 'Failed to load categories'); }assets/js/wpuf-form-builder.js (7)
44-45
: Good backward compatibility approach.The change from
'form-fields'
to'form-fields-v4-1'
indicates an update to the panel system, and I appreciate that you've kept support for both panel names to maintain backward compatibility. This approach ensures existing implementations continue to work while enabling the new features.Also applies to: 71-73
91-108
: Potential undefined index access.The code accesses
field[0]
but doesn't verify the array has elements before the conditional on line 96. While there's a check forfield.length
on line 100, this doesn't completely eliminate the risk in the first condition.- if ('field-options' === state.current_panel && field[0].id === state.editing_field_id) { + if ('field-options' === state.current_panel && field.length && field[0].id === state.editing_field_id) { return; }
168-187
: Improved error messaging with internationalization support.The enhanced SweetAlert configuration provides better styling and internationalization support through wp.i18n. The image inclusion and styling improvements create a more engaging user experience.
393-401
: Good addition of state management mutations.Adding dedicated mutations for panel section management is a good practice. These new methods provide a clear API for updating panel sections and resetting to defaults, improving the maintainability of the code.
652-669
: Good use of utility classes for consistent styling.The
setting_class_names
method provides a centralized way to manage CSS classes for different field types, which improves maintainability and ensures consistent styling across components.
713-1055
: Excellent implementation of a dependency management system.The
FormDependencyHandler
class provides a robust way to manage field dependencies and visibility rules. The approach with specific methods for initialization, visibility checking, and event attachment is well-structured and maintainable.Some suggested improvements:
- Consider adding JSDoc comments to document the class methods
- The class could be made more reusable by moving it to a separate file
- Adding unit tests would help ensure its reliability
1066-1105
: Good dynamic category handling for post types.The implementation for dynamically updating category fields based on post type selection improves the user experience. The AJAX approach with proper error handling is well-implemented.
assets/js/wpuf-form-builder-mixins.js (6)
24-33
: Improved error notification design.The enhanced error notification for duplicate fields provides better visual feedback with styled HTML and an image. This creates a more user-friendly experience when validation errors occur.
60-64
: Good implementation of pro feature detection.The
is_pro_preview
method provides a clean way to determine if a template is a pro-only feature and whether the user has access to it. This facilitates showing appropriate UI and messaging based on the user's subscription status.
82-83
: Improved default prop value pattern.Using a function that returns an object rather than a direct object reference is the correct approach for default prop values in Vue. This prevents the sharing of object references between component instances and avoids unexpected side effects.
109-139
: Good encapsulation of class handling for form elements.The
builder_class_names
method provides a centralized approach to managing CSS classes for different field types. This helps maintain consistency across the application and makes styling changes easier to implement.The use of TailwindCSS-style utility classes with namespacing (
wpuf-
prefix) is a good approach to prevent CSS conflicts with other plugins or themes.
329-330
: Consistent use of default prop value pattern.Using the same function-returning-object pattern for default prop values across the codebase ensures consistency and prevents shared state issues. Good implementation.
Also applies to: 333-335
169-175
: Useful computed properties for pro version status.Adding computed properties for pro status and links improves code readability and reusability across components. This is a good practice for features that might be used in multiple places.
src/css/admin/form-builder.css (1)
1-51
: LGTM: Tailwind CSS structure is well organized.The Tailwind CSS structure is well organized with proper layer definitions for components and utilities.
border: 1px dashed #ddd; | ||
background-color: #ffffff; | ||
opacity: 1; | ||
background: repeating-linear-gradient( -45deg, #dcfce7, #dcfce7 2px, #ffffff 2px, #ffffff 6px ); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix duplicate background property.
The element defines both background-color
and background
which causes the first property to be overridden.
Apply this fix:
- background-color: #ffffff;
- opacity: 1;
- background: repeating-linear-gradient( -45deg, #dcfce7, #dcfce7 2px, #ffffff 2px, #ffffff 6px );
+ opacity: 1;
+ background: repeating-linear-gradient( -45deg, #dcfce7, #dcfce7 2px, #ffffff 2px, #ffffff 6px );
📝 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.
border: 1px dashed #ddd; | |
background-color: #ffffff; | |
opacity: 1; | |
background: repeating-linear-gradient( -45deg, #dcfce7, #dcfce7 2px, #ffffff 2px, #ffffff 6px ); | |
} | |
border: 1px dashed #ddd; | |
opacity: 1; | |
background: repeating-linear-gradient( -45deg, #dcfce7, #dcfce7 2px, #ffffff 2px, #ffffff 6px ); | |
} |
🧰 Tools
🪛 Biome (1.9.4)
[error] 70-70: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
field-sizing: content; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix invalid CSS property and missing closing brace.
The file contains an invalid CSS property field-sizing: content;
and is missing a closing brace at the end.
Apply this fix:
- field-sizing: content;
+ /* If you meant to use box-sizing */
+ box-sizing: content-box;
+}
📝 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.
field-sizing: content; | |
} | |
/* If you meant to use box-sizing */ | |
box-sizing: content-box; | |
} |
🧰 Tools
🪛 Biome (1.9.4)
[error] 221-221: expected }
but instead the file ends
the file ends here
(parse)
</span> | ||
</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix unclosed span tag.
There is an extra closing </span>
tag without a matching opening tag.
Apply this fix:
- </span>
📝 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.
</span> | |
</span> | |
</span> |
title="<?php printf( esc_html( __( 'Click to copy shortcode', 'wp-user-frontend' ) ) ); ?>" | ||
data-clipboard-text="<?php printf( esc_attr( '[' . $shortcodes[0]['name'] . ' id="' . esc_attr( $form_id ) . '"]' ) ); ?>">#{{ post.ID }} | ||
<span id="default-icon" class="wpuf-ml-2"> | ||
<svg | ||
v-if="!shortcodeCopied" | ||
class="group-hover:wpuf-rotate-6 group-hover:wpuf-stroke-gray-500 wpuf-stroke-gray-400" | ||
width="20" | ||
height="20" | ||
viewBox="0 0 20 20" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg"> | ||
<path d="M13.125 14.375V17.1875C13.125 17.7053 12.7053 18.125 12.1875 18.125H4.0625C3.54473 18.125 3.125 17.7053 3.125 17.1875V6.5625C3.125 6.04473 3.54473 5.625 4.0625 5.625H5.625C6.05089 5.625 6.46849 5.6605 6.875 5.7287M13.125 14.375H15.9375C16.4553 14.375 16.875 13.9553 16.875 13.4375V9.375C16.875 5.65876 14.1721 2.5738 10.625 1.9787C10.2185 1.9105 9.80089 1.875 9.375 1.875H7.8125C7.29473 1.875 6.875 2.29473 6.875 2.8125V5.7287M13.125 14.375H7.8125C7.29473 14.375 6.875 13.9553 6.875 13.4375V5.7287M16.875 11.25V9.6875C16.875 8.1342 15.6158 6.875 14.0625 6.875H12.8125C12.2947 6.875 11.875 6.45527 11.875 5.9375V4.6875C11.875 3.1342 10.6158 1.875 9.0625 1.875H8.125" stroke="#6B7280" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> | ||
</svg> | ||
<svg | ||
v-if="shortcodeCopied" | ||
class="wpuf-rotate-6 !wpuf-stroke-primary wpuf-mt-[-5px]" | ||
width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
<path d="M12.2392 3V5.15403M7.81196 4.54199L9.22618 6.06512M16.6663 4.54199L15.2521 6.06512M14.4438 8.66349C14.2661 7.98485 13.687 7.48747 13 7.48747H11C10.313 7.48747 9.73391 7.98485 9.55618 8.66349M14.4438 8.66349C14.4804 8.80322 14.5 8.95064 14.5 9.10299C14.5 9.4004 14.2761 9.6415 14 9.6415H10C9.72386 9.6415 9.5 9.4004 9.5 9.10299C9.5 8.95064 9.51958 8.80322 9.55618 8.66349M14.4438 8.66349C14.8746 8.69852 15.303 8.74275 15.7289 8.79598C16.4626 8.88769 17 9.56898 17 10.3645V19.3845C17 20.2767 16.3284 21 15.5 21H8.5C7.67157 21 7 20.2767 7 19.3845V10.3645C7 9.56898 7.53739 8.88769 8.27112 8.79598C8.69698 8.74275 9.12539 8.69852 9.55618 8.66349M9.99997 13.8997H14M9.99997 16.5H12" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> | ||
</svg> | ||
</span> | ||
</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add keyboard accessibility for copying shortcodes.
The shortcode copy functionality lacks keyboard support for users who navigate without a mouse.
Enhance the shortcode block with keyboard support:
<span
class="form-id wpuf-group wpuf-flex wpuf-items-center wpuf-px-[18px] wpuf-py-[10px] wpuf-rounded-md wpuf-border wpuf-border-gray-300 hover:wpuf-cursor-pointer wpuf-ml-6 wpuf-text-gray-700 wpuf-text-base wpuf-leading-none wpuf-shadow-sm"
title="<?php printf( esc_html( __( 'Click to copy shortcode', 'wp-user-frontend' ) ) ); ?>"
+ tabindex="0"
+ role="button"
+ @keydown.enter="copyToClipboard"
+ @keydown.space.prevent="copyToClipboard"
data-clipboard-text="<?php printf( esc_attr( '[' . $shortcodes[0]['name'] . ' id="' . esc_attr( $form_id ) . '"]' ) ); ?>">#{{ post.ID }}
This assumes you have a copyToClipboard
method in your Vue component. If not, you'll need to create one.
📝 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.
title="<?php printf( esc_html( __( 'Click to copy shortcode', 'wp-user-frontend' ) ) ); ?>" | |
data-clipboard-text="<?php printf( esc_attr( '[' . $shortcodes[0]['name'] . ' id="' . esc_attr( $form_id ) . '"]' ) ); ?>">#{{ post.ID }} | |
<span id="default-icon" class="wpuf-ml-2"> | |
<svg | |
v-if="!shortcodeCopied" | |
class="group-hover:wpuf-rotate-6 group-hover:wpuf-stroke-gray-500 wpuf-stroke-gray-400" | |
width="20" | |
height="20" | |
viewBox="0 0 20 20" | |
fill="none" | |
xmlns="http://www.w3.org/2000/svg"> | |
<path d="M13.125 14.375V17.1875C13.125 17.7053 12.7053 18.125 12.1875 18.125H4.0625C3.54473 18.125 3.125 17.7053 3.125 17.1875V6.5625C3.125 6.04473 3.54473 5.625 4.0625 5.625H5.625C6.05089 5.625 6.46849 5.6605 6.875 5.7287M13.125 14.375H15.9375C16.4553 14.375 16.875 13.9553 16.875 13.4375V9.375C16.875 5.65876 14.1721 2.5738 10.625 1.9787C10.2185 1.9105 9.80089 1.875 9.375 1.875H7.8125C7.29473 1.875 6.875 2.29473 6.875 2.8125V5.7287M13.125 14.375H7.8125C7.29473 14.375 6.875 13.9553 6.875 13.4375V5.7287M16.875 11.25V9.6875C16.875 8.1342 15.6158 6.875 14.0625 6.875H12.8125C12.2947 6.875 11.875 6.45527 11.875 5.9375V4.6875C11.875 3.1342 10.6158 1.875 9.0625 1.875H8.125" stroke="#6B7280" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> | |
</svg> | |
<svg | |
v-if="shortcodeCopied" | |
class="wpuf-rotate-6 !wpuf-stroke-primary wpuf-mt-[-5px]" | |
width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |
<path d="M12.2392 3V5.15403M7.81196 4.54199L9.22618 6.06512M16.6663 4.54199L15.2521 6.06512M14.4438 8.66349C14.2661 7.98485 13.687 7.48747 13 7.48747H11C10.313 7.48747 9.73391 7.98485 9.55618 8.66349M14.4438 8.66349C14.4804 8.80322 14.5 8.95064 14.5 9.10299C14.5 9.4004 14.2761 9.6415 14 9.6415H10C9.72386 9.6415 9.5 9.4004 9.5 9.10299C9.5 8.95064 9.51958 8.80322 9.55618 8.66349M14.4438 8.66349C14.8746 8.69852 15.303 8.74275 15.7289 8.79598C16.4626 8.88769 17 9.56898 17 10.3645V19.3845C17 20.2767 16.3284 21 15.5 21H8.5C7.67157 21 7 20.2767 7 19.3845V10.3645C7 9.56898 7.53739 8.88769 8.27112 8.79598C8.69698 8.74275 9.12539 8.69852 9.55618 8.66349M9.99997 13.8997H14M9.99997 16.5H12" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> | |
</svg> | |
</span> | |
</span> | |
<span | |
class="form-id wpuf-group wpuf-flex wpuf-items-center wpuf-px-[18px] wpuf-py-[10px] wpuf-rounded-md wpuf-border wpuf-border-gray-300 hover:wpuf-cursor-pointer wpuf-ml-6 wpuf-text-gray-700 wpuf-text-base wpuf-leading-none wpuf-shadow-sm" | |
title="<?php printf( esc_html( __( 'Click to copy shortcode', 'wp-user-frontend' ) ) ); ?>" | |
tabindex="0" | |
role="button" | |
@keydown.enter="copyToClipboard" | |
@keydown.space.prevent="copyToClipboard" | |
data-clipboard-text="<?php printf( esc_attr( '[' . $shortcodes[0]['name'] . ' id="' . esc_attr( $form_id ) . '"]' ) ); ?>">#{{ post.ID }} | |
<span id="default-icon" class="wpuf-ml-2"> | |
<svg | |
v-if="!shortcodeCopied" | |
class="group-hover:wpuf-rotate-6 group-hover:wpuf-stroke-gray-500 wpuf-stroke-gray-400" | |
width="20" | |
height="20" | |
viewBox="0 0 20 20" | |
fill="none" | |
xmlns="http://www.w3.org/2000/svg"> | |
<path d="M13.125 14.375V17.1875C13.125 17.7053 12.7053 18.125 12.1875 18.125H4.0625C3.54473 18.125 3.125 17.7053 3.125 17.1875V6.5625C3.125 6.04473 3.54473 5.625 4.0625 5.625H5.625C6.05089 5.625 6.46849 5.6605 6.875 5.7287M13.125 14.375H15.9375C16.4553 14.375 16.875 13.9553 16.875 13.4375V9.375C16.875 5.65876 14.1721 2.5738 10.625 1.9787C10.2185 1.9105 9.80089 1.875 9.375 1.875H7.8125C7.29473 1.875 6.875 2.29473 6.875 2.8125V5.7287M13.125 14.375H7.8125C7.29473 14.375 6.875 13.9553 6.875 13.4375V5.7287M16.875 11.25V9.6875C16.875 8.1342 15.6158 6.875 14.0625 6.875H12.8125C12.2947 6.875 11.875 6.45527 11.875 5.9375V4.6875C11.875 3.1342 10.6158 1.875 9.0625 1.875H8.125" stroke="#6B7280" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> | |
</svg> | |
<svg | |
v-if="shortcodeCopied" | |
class="wpuf-rotate-6 !wpuf-stroke-primary wpuf-mt-[-5px]" | |
width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |
<path d="M12.2392 3V5.15403M7.81196 4.54199L9.22618 6.06512M16.6663 4.54199L15.2521 6.06512M14.4438 8.66349C14.2661 7.98485 13.687 7.48747 13 7.48747H11C10.313 7.48747 9.73391 7.98485 9.55618 8.66349M14.4438 8.66349C14.4804 8.80322 14.5 8.95064 14.5 9.10299C14.5 9.4004 14.2761 9.6415 14 9.6415H10C9.72386 9.6415 9.5 9.4004 9.5 9.10299C9.5 8.95064 9.51958 8.80322 9.55618 8.66349M14.4438 8.66349C14.8746 8.69852 15.303 8.74275 15.7289 8.79598C16.4626 8.88769 17 9.56898 17 10.3645V19.3845C17 20.2767 16.3284 21 15.5 21H8.5C7.67157 21 7 20.2767 7 19.3845V10.3645C7 9.56898 7.53739 8.88769 8.27112 8.79598C8.69698 8.74275 9.12539 8.69852 9.55618 8.66349M9.99997 13.8997H14M9.99997 16.5H12" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> | |
</svg> | |
</span> | |
</span> |
@click="showOptions = !showOptions" | ||
class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-min-w-full wpuf-rounded-md wpuf-py-1 wpuf-px-2 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full hover:wpuf-cursor-pointer" | ||
> | ||
{{ selectedOption }} | ||
<i | ||
:class="showOptions ? 'fa-angle-up' : 'fa-angle-down'" | ||
class="fa"></i> | ||
</p> | ||
|
||
<div | ||
v-if="showOptions" | ||
class="wpuf-absolute wpuf-bg-white wpuf-border wpuf-border-gray-300 wpuf-rounded-lg wpuf-w-full wpuf-z-10 wpuf--mt-4"> | ||
<ul> | ||
<li | ||
v-for="(option, key) in option_field.options" | ||
@click="[value = key, showOptions = false, selectedOption = option]" | ||
:value="key" | ||
class="wpuf-text-sm wpuf-color-gray-900 wpuf-py-2 wpuf-px-4 hover:wpuf-cursor-pointer hover:wpuf-bg-gray-100">{{ option }}</li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add filter or validation to prevent XSS in option content.
Direct binding of option content could allow XSS attacks if the data comes from user input.
Add sanitization for option values:
<p
@click="showOptions = !showOptions"
class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-min-w-full wpuf-rounded-md wpuf-py-1 wpuf-px-2 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full hover:wpuf-cursor-pointer"
>
- {{ selectedOption }}
+ {{ sanitizeHTML(selectedOption) }}
<i
:class="showOptions ? 'fa-angle-up' : 'fa-angle-down'"
class="fa"></i>
</p>
<div
v-if="showOptions"
class="wpuf-absolute wpuf-bg-white wpuf-border wpuf-border-gray-300 wpuf-rounded-lg wpuf-w-full wpuf-z-10 wpuf--mt-4">
<ul>
<li
v-for="(option, key) in option_field.options"
- @click="[value = key, showOptions = false, selectedOption = option]"
+ @click="[value = key, showOptions = false, selectedOption = sanitizeHTML(option)]"
:value="key"
- class="wpuf-text-sm wpuf-color-gray-900 wpuf-py-2 wpuf-px-4 hover:wpuf-cursor-pointer hover:wpuf-bg-gray-100">{{ option }}</li>
+ class="wpuf-text-sm wpuf-color-gray-900 wpuf-py-2 wpuf-px-4 hover:wpuf-cursor-pointer hover:wpuf-bg-gray-100">{{ sanitizeHTML(option) }}</li>
</ul>
</div>
And add the sanitization method to your component:
methods: {
sanitizeHTML(str) {
if (!str) return '';
return String(str)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
}
<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> | ||
<li class="wpuf-submit wpuf-list-none wpuf-hidden"> | ||
<div class="wpuf-label"> </div> | ||
<?php do_action( 'wpuf_form_builder_template_builder_stage_submit_area' ); ?> | ||
</li> | ||
<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/hidden-fields !wpuf-m-0 !wpuf-p-0 hover:wpuf-cursor-pointer" | ||
> | ||
<div | ||
:class="parseInt(editing_form_id) === parseInt(field.id) ? 'wpuf-bg-green-50 wpuf-border-green-400' : 'wpuf-border-transparent'" | ||
class="wpuf-flex wpuf-rounded-t-lg wpuf-border-t wpuf-border-r wpuf-border-l wpuf-border-dashed group-hover/hidden-fields:wpuf-border-green-400 group-hover/hidden-fields:wpuf-bg-green-50"> | ||
<div class="wpuf-bg-orange-100 wpuf-m-4 wpuf-py-2 wpuf-px-4 wpuf-w-full wpuf-rounded-lg"> | ||
<strong><?php esc_html_e( 'key', 'wp-user-frontend' ); ?></strong>: {{ field.name }} | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix potential XSS vulnerability in field label display.
Field labels are rendered directly without sanitization, which could lead to XSS attacks if user input is reflected.
Add sanitization for field labels:
<div v-if="!(is_full_width(field.template) || is_pro_preview(field.template))" class="wpuf-w-1/4">
<label
v-if="!is_invisible(field)"
:for="'wpuf-' + field.name ? field.name : 'cls'"
class="wpuf-block wpuf-text-sm wpuf-font-medium wpuf-leading-6 wpuf-text-gray-900">
- {{ field.label }} <span v-if="field.required && 'yes' === field.required"
+ {{ sanitizeHTML(field.label) }} <span v-if="field.required && 'yes' === field.required"
class="required">*</span>
</label>
</div>
And in the pro version preview:
<div v-if="is_pro_preview(field.template)" class="stage-pro-alert wpuf-text-center">
<label class="wpuf-pro-text-alert">
<a :href="pro_link" target="_blank"
- class="wpuf-text-gray-700 wpuf-text-base"><strong>{{ get_field_name( field.template )
+ class="wpuf-text-gray-700 wpuf-text-base"><strong>{{ sanitizeHTML(get_field_name( field.template ))
}}</strong> <?php _e( 'is available in Pro Version', 'wp-user-frontend' ); ?></a>
</label>
</div>
Add the sanitization method to your component:
methods: {
sanitizeHTML(str) {
if (!str) return '';
return String(str)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
}
<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_preview(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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add keyboard accessibility for form fields list.
Users navigating by keyboard cannot interact with form fields without proper keyboard event handlers.
Add keyboard support for the form fields list:
<li
v-for="(field, index) in form_fields"
:key="field.id"
:data-index="index"
data-source="stage"
+ tabindex="0"
+ @keydown.enter="open_field_settings(field.id)"
+ @keydown.space.prevent="open_field_settings(field.id)"
+ @keydown.delete="delete_field(index)"
:class="[
'field-items', 'wpuf-el', field.name, field.css, 'form-field-' + field.template,
field.width ? 'field-size-' + field.width : '',
('custom_hidden_field' === field.template) ? 'hidden-field' : ''
]"
class="wpuf-group wpuf-rounded-lg hover:!wpuf-bg-green-50 wpuf-transition wpuf-duration-150 wpuf-ease-out !wpuf-m-0 !wpuf-p-0">
📝 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.
<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_preview(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> | |
<li | |
v-for="(field, index) in form_fields" | |
:key="field.id" | |
:data-index="index" | |
data-source="stage" | |
tabindex="0" | |
@keydown.enter="open_field_settings(field.id)" | |
@keydown.space.prevent="open_field_settings(field.id)" | |
@keydown.delete="delete_field(index)" | |
:class="[ | |
'field-items', 'wpuf-el', field.name, field.css, 'form-field-' + field.template, | |
field.width ? 'field-size-' + field.width : '', | |
('custom_hidden_field' === field.template) ? 'hidden-field' : '' | |
]" | |
class="wpuf-group wpuf-rounded-lg hover:!wpuf-bg-green-50 wpuf-transition wpuf-duration-150 wpuf-ease-out !wpuf-m-0 !wpuf-p-0"> | |
<!-- existing li content --> | |
</li> |
class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-min-w-full wpuf-rounded-md wpuf-py-1 wpuf-px-2 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full hover:wpuf-cursor-pointer" | ||
> | ||
{{ selectedOption }} | ||
<i | ||
:class="showOptions ? 'fa-angle-up' : 'fa-angle-down'" | ||
class="fa"></i> | ||
</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve the custom dropdown implementation across templates.
Similar to the field-select component, this custom dropdown also lacks proper accessibility features.
Apply the same accessibility enhancements here:
<p
@click="showOptions = !showOptions"
+ @keydown.enter="showOptions = !showOptions"
+ @keydown.space.prevent="showOptions = !showOptions"
+ role="combobox"
+ :aria-expanded="showOptions"
+ tabindex="0"
class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-min-w-full wpuf-rounded-md wpuf-py-1 wpuf-px-2 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full hover:wpuf-cursor-pointer"
>
{{ selectedOption }}
<i
:class="showOptions ? 'fa-angle-up' : 'fa-angle-down'"
class="fa"
+ aria-hidden="true"
></i>
</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.
class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-min-w-full wpuf-rounded-md wpuf-py-1 wpuf-px-2 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full hover:wpuf-cursor-pointer" | |
> | |
{{ selectedOption }} | |
<i | |
:class="showOptions ? 'fa-angle-up' : 'fa-angle-down'" | |
class="fa"></i> | |
</p> | |
<p | |
@click="showOptions = !showOptions" | |
@keydown.enter="showOptions = !showOptions" | |
@keydown.space.prevent="showOptions = !showOptions" | |
role="combobox" | |
:aria-expanded="showOptions" | |
tabindex="0" | |
class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-min-w-full wpuf-rounded-md wpuf-py-1 wpuf-px-2 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full hover:wpuf-cursor-pointer" | |
> | |
{{ selectedOption }} | |
<i | |
:class="showOptions ? 'fa-angle-up' : 'fa-angle-down'" | |
class="fa" | |
aria-hidden="true" | |
></i> | |
</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/css/admin/form-builder.css (1)
219-221
:⚠️ Potential issueInvalid CSS Property in Field Sizing Class.
The property
field-sizing: content;
in.wpuf-field-sizing-content
is not a valid CSS property. It appears you intended to use a box model property (e.g.,box-sizing: content-box;
). Please update the declaration accordingly.Example diff:
- field-sizing: content; + box-sizing: content-box;
🧹 Nitpick comments (2)
src/css/admin/form-builder.css (2)
18-20
: Checkbox Styling: Minor Punctuation Note.The
.wpuf-input-checkbox
class is defined using utility classes. Although not strictly required, consider adding a semicolon after the final property for consistency.
168-176
: Range Input Styling is Functional.The base styles for range inputs (e.g., width, height, background, border-radius) are clear. For consistency, consider adding a semicolon after the
border-radius: 10px
rule (line 175).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
admin/form-builder/assets/js/mixins/form-field.js
(3 hunks)assets/js/wpuf-form-builder-mixins.js
(7 hunks)src/css/admin/form-builder.css
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- admin/form-builder/assets/js/mixins/form-field.js
🧰 Additional context used
🪛 Biome (1.9.4)
src/css/admin/form-builder.css
[error] 225-225: expected }
but instead the file ends
the file ends here
(parse)
[error] 70-70: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
🔇 Additional comments (39)
assets/js/wpuf-form-builder-mixins.js (6)
24-33
: Enhanced error notification with better styling.The error notification for duplicate fields has been significantly improved with styled title, formatted HTML content, and an image instead of just text. This provides a better user experience with clear visual cues.
60-64
: Good addition of pro feature detection method.The
is_pro_preview
method provides a clean way to check if a template is a pro feature and whether the pro version is active, which will help with conditional rendering of premium features.
67-70
: Standardized action button styling.Adding the
action_button_classes
computed property provides consistent styling for action buttons across the form builder interface.
109-139
: Well-structured builder class naming system with Tailwind CSS.The new
builder_class_names
method provides a comprehensive approach to styling different field types using Tailwind CSS utility classes. This creates consistency across the form builder interface and makes styling more maintainable.However, the extensive use of Tailwind's
!important
modifiers (using the!
prefix) suggests there might be some CSS specificity issues that had to be overridden. Consider reviewing your CSS architecture to minimize the need for these forceful overrides in the future.
169-174
: Useful pro-related computed properties.Adding the
is_pro_active
andpro_link
computed properties to the global mixin makes it easier to access this information throughout the application, improving code maintainability.
329-329
: Fixed Vue prop object default values in option_field_mixin.Similar to the change in the
field
prop, using functions to return default objects for theoption_field
andediting_form_field
props follows Vue best practices and prevents shared references between instances.Also applies to: 334-334
src/css/admin/form-builder.css (33)
1-3
: Tailwind Setup Directives are Correct.The directives for Tailwind (
@tailwind base;
,@tailwind components;
, and@tailwind utilities;
) correctly initialize the framework.
5-9
: Component Layer: Clear and Consistent.The use of the
@layer components
block with utility classes (e.g., for.wpuf-btn-primary
) is well structured and leverages Tailwind CSS effectively.
10-12
: Secondary Button Styling is Solid.The
.wpuf-btn-secondary
class’s use of Tailwind utilities is consistent with the design approach.
14-16
: Tooltip Styling is Well-Defined.The
.wpuf-tooltip-top
class employs pseudo-element utilities cleanly, ensuring good tooltip presentation.
22-24
: Pill Element Styling Looks Consistent.The styles for
.wpuf-pill-green
effectively combine color, border, and spacing utilities.
26-32
: Panel Field Option Styling is Clear.The margin and flex layout applied via Tailwind classes ensure proper spacing and alignment within panel field options.
35-51
: Utility Layer Definitions are Precise.The custom utilities under
@layer utilities
for transitions and scaling (e.g.,.wpuf-transition-all
,.wpuf-duration-100
, etc.) are succinct and enhance consistency.
53-55
: Content Area Background is Defined.The rule for
#wpcontent
setting a white background is straightforward and clear.
57-60
: Dropdown Item Transition Styles are Well-Implemented.The application of transition utilities to
.wpuf-dropdown-item
ensures smooth visual effects.
62-64
: Dropdown Container Hover Effect is Intuitive.The hover state for
.wpuf-dropdown-container
that reveals the dropdown items is clear and effective.
66-71
: Duplicate Background Property in Pattern Class.In the
.wpuf-pattern-1
class, bothbackground-color: #ffffff;
(line 68) and the shorthandbackground
(line 70) are declared, causing the former to be overridden. Given previous feedback, consider removing thebackground-color
property if it is not needed as a fallback.Example diff:
- background-color: #ffffff;
🧰 Tools
🪛 Biome (1.9.4)
[error] 70-70: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
73-76
: Selectize Data-Value Styling is Appropriate.The styling for
[data-value]
within.selectize-control.multi .selectize-input
is directly applied with necessary!important
flags to enforce the design.
77-97
: Responsive Form Field Widths Maintained.The various width settings for elements (e.g., small, medium, large fields) are logical and maintain layout consistency throughout the form.
98-100
: Uniform Width for Field Items.The rule for body ul.wpuf-form li .wpuf-fields setting a 70% width ensures consistent layout behavior.
101-104
: Sidebar SVG Icon Default Stroke is Clear.The default stroke color for SVG icons within the sidebar is clearly defined and aligns with the overall admin style.
105-110
: Active and Hover States for Sidebar SVG Icons are Well-Handled.The contrasting stroke color on hover and for active states enhances visual feedback for menu interactions.
111-115
: Selectize Control Base Styles are Set Effectively.The removal of borders, shadows, and padding via important overrides is clearly intended; just ensure these do not conflict with any external library defaults.
116-121
: Selectize Single Control Styling is Consistent.The single-select control styles with border and background settings maintain a clean appearance.
122-128
: Icon Container Layout is Solid.The
.wpuf-icon-container
class properly manages positioning, sizing, and overflow for icon elements.
129-131
: Loaded Icon Container Styling is Appropriate.The adjustment of background settings for the loaded state in
.wpuf-icon-container.wpuf-is-loaded
is concise and effective.
132-141
: Image Styling Within Icon Container is Well-Established.Absolute positioning with object-fit settings ensures that images scale correctly and smoothly transition their opacity.
142-145
: Opacity Transition for Loaded Icons is Correct.The rule that sets opacity to 1 for loaded images and iframes ensures a smooth display transition.
146-160
: Shimmer Effect Configuration is Clear and Effective.The keyframe animation and transition settings for
.wpuf-shimmer
are neatly defined and provide a smooth loading effect.
161-164
: Shimmer Keyframes are Accurately Defined.The keyframes for
wpuf-shimmer
correctly animate the shimmer effect over the element.
165-167
: Hiding Shimmer on Loaded Icons Works Well.Applying
display: none;
to the shimmer effect when the icon is loaded is an effective approach.
177-185
: Webkit Slider Thumb Styles are Consistent.The declarations for the slider thumb in WebKit ensure a proper appearance and interactivity.
186-192
: Mozilla Range Thumb Styling is Accurate.The rules for
::-moz-range-thumb
are consistent with those for WebKit, ensuring a uniform look across browsers.
193-196
: Range Input Hover/Active States are Well-Covered.The styling for hover and active states on range inputs maintain consistent background behavior.
197-202
: Enhanced Hover States for Range Thumbs are Clear.The additional hover and active styles for slider thumbs further refine user interaction feedback.
203-205
: Table Cell Padding is Defined Adequately.The padding for table cells in
.option-field-option-chooser
promotes legibility and proper spacing.
206-214
: Selectize Input After-Element is Configured Well.The use of FontAwesome for the dropdown indicator in
.selectize-control.single .selectize-input:after
is effective. Verify that the provided icon code (\f107
) is supported by the version of FontAwesome in use.
215-218
: Active Dropdown Indicator Styling Maintains Consistency.The adjustments for the dropdown-active after-element assure a consistent visual state when active.
222-225
: Ensure Proper Closure for Core UI Select Rules.While the
.wp-core-ui select
block appears to be correctly defined, static analysis flagged a missing closing brace. Please verify that the block is properly terminated and that the file ends correctly with no parsing errors.🧰 Tools
🪛 Biome (1.9.4)
[error] 225-225: expected
}
but instead the file endsthe file ends here
(parse)
@@ -59,7 +79,7 @@ wpuf_mixins.form_field_mixin = { | |||
props: { | |||
field: { | |||
type: Object, | |||
default: {} | |||
default: () => ({ key: 'value' }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fixed Vue prop object default value.
Using a function to return the default object value for the field
prop is a Vue best practice. This prevents multiple component instances from sharing the same default object reference, which could lead to unexpected behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
♻️ Duplicate comments (3)
admin/form-builder/assets/js/form-builder.js (1)
580-580
: 🛠️ Refactor suggestionSimplify boolean toggling.
The static analysis tool correctly identified an unnecessary ternary operation. This can be simplified.
-this.is_form_switcher = (this.is_form_switcher) ? false : true; +this.is_form_switcher = !this.is_form_switcher;🧰 Tools
🪛 Biome (1.9.4)
[error] 580-580: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with(lint/complexity/noUselessTernary)
assets/js/wpuf-form-builder-mixins.js (1)
82-82
: 🛠️ Refactor suggestionFixed Vue prop object default value.
Using a function to return the default object value for the
field
prop is a Vue best practice. This prevents multiple component instances from sharing the same default object reference, which could lead to unexpected behavior.assets/js/wpuf-form-builder.js (1)
585-587
: 🛠️ Refactor suggestionUse store mutations, not direct property assignments.
Setting
this.$store.state.panel_sections
outside a mutation bypasses Vuex reactivity best practices. Wrap updates in either a mutation or an action to ensure consistent state changes.
🧹 Nitpick comments (8)
src/css/admin/form-builder.css (1)
168-176
: Range Input StylingThe styles for the range input (including appearance, dimensions, and transitions) are well defined. For consistency, consider ending the border-radius property with a semicolon.
assets/js-templates/form-components.php (7)
85-91
: Duplicate text in the empty form state.There's duplicate text in the message shown when there are no form fields. Both the heading and paragraph have the exact same text.
<div v-if="!form_fields.length" class="wpuf-flex wpuf-flex-col wpuf-items-center wpuf-justify-center wpuf-h-[80vh]"> <img src="<?php echo WPUF_ASSET_URI . '/images/form-blank-state.svg'; ?>" alt=""> <h2 class="wpuf-text-lg wpuf-text-gray-800 wpuf-mt-8 wpuf-mb-2"><?php esc_html_e( 'Add fields and build your desired form', 'wp-user-frontend' ); ?></h2> - <p class="wpuf-text-sm wpuf-text-gray-500"><?php esc_html_e( 'Add fields and build your desired form', 'wp-user-frontend' ); ?></p> + <p class="wpuf-text-sm wpuf-text-gray-500"><?php esc_html_e( 'Drag fields from the right sidebar to this area to create your form', 'wp-user-frontend' ); ?></p> </div>
193-200
: Improve SVG icon accessibility.The SVG icon lacks proper accessibility attributes, making it difficult for screen readers to interpret.
<svg width="15" height="15" viewBox="0 0 20 15" fill="none" + aria-hidden="true" + role="img" + focusable="false" 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>Apply similar changes to all SVG icons in the file for consistent accessibility support.
1054-1056
: Add ARIA label to search field for improved accessibility.The search field lacks an appropriate ARIA label, which could make it difficult for screen reader users to understand its purpose.
<input type="text" name="search" id="search" v-model="searched_fields" + aria-label="<?php esc_attr_e( 'Search for fields', 'wp-user-frontend' ); ?>" class="!wpuf-border-none !wpuf-rounded-[6px] 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-ring-transparent wpuf-shadow focus:!wpuf-shadow-none" placeholder="<?php esc_attr_e( 'Search Field', 'wp-user-frontend' ); ?>">
824-835
: Inconsistent label rendering in column fields.In column fields, the label rendering is inconsistent with the main field template and may not handle accessibility properly.
<label v-if="!is_invisible(field)" :for="'wpuf-' + (field.name ? field.name : 'cls')" - class="wpuf-block wpuf-text-sm"> + class="wpuf-block wpuf-text-sm wpuf-font-medium wpuf-leading-6 wpuf-text-gray-900"> {{ field.label }} <span v-if="field.required && 'yes' === field.required" class="required">*</span> </label>
89-90
: Add descriptive alt text to the form blank state image.The blank state image is missing descriptive alt text, which affects accessibility for screen reader users.
<div v-if="!form_fields.length" class="wpuf-flex wpuf-flex-col wpuf-items-center wpuf-justify-center wpuf-h-[80vh]"> - <img src="<?php echo WPUF_ASSET_URI . '/images/form-blank-state.svg'; ?>" alt=""> + <img src="<?php echo WPUF_ASSET_URI . '/images/form-blank-state.svg'; ?>" alt="<?php esc_attr_e( 'Form editor blank state', 'wp-user-frontend' ); ?>"> <h2 class="wpuf-text-lg wpuf-text-gray-800 wpuf-mt-8 wpuf-mb-2"><?php esc_html_e( 'Add fields and build your desired form', 'wp-user-frontend' ); ?></h2> <p class="wpuf-text-sm wpuf-text-gray-500"><?php esc_html_e( 'Add fields and build your desired form', 'wp-user-frontend' ); ?></p> </div>
1117-1117
: Add alt text to PRO feature image icon.The PRO feature icon image is missing alt text, which affects accessibility for screen reader users.
- <img src="<?php esc_attr_e( WPUF_ASSET_URI . '/images/crown.svg' ); ?>" alt=""> + <img src="<?php esc_attr_e( WPUF_ASSET_URI . '/images/crown.svg' ); ?>" alt="<?php esc_attr_e( 'Premium feature', 'wp-user-frontend' ); ?>">
206-209
: Fix potential inconsistency with hidden submit button.The submit button is hidden with CSS but still present in the DOM, which could lead to unexpected behavior. Consider using v-if/v-show for better control.
- <li class="wpuf-submit wpuf-list-none wpuf-hidden"> + <li v-show="false" class="wpuf-submit wpuf-list-none"> <div class="wpuf-label"> </div> <?php do_action( 'wpuf_form_builder_template_builder_stage_submit_area' ); ?> </li>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
admin/form-builder/assets/js/components/field-checkbox/template.php
(1 hunks)admin/form-builder/assets/js/form-builder.js
(14 hunks)admin/form-builder/assets/js/mixins/form-field.js
(3 hunks)assets/js-templates/form-components.php
(16 hunks)assets/js/wpuf-form-builder-mixins.js
(7 hunks)assets/js/wpuf-form-builder.js
(14 hunks)src/css/admin/form-builder.css
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- admin/form-builder/assets/js/mixins/form-field.js
- admin/form-builder/assets/js/components/field-checkbox/template.php
🧰 Additional context used
🪛 Biome (1.9.4)
admin/form-builder/assets/js/form-builder.js
[error] 580-580: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
assets/js/wpuf-form-builder.js
[error] 580-580: 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)
src/css/admin/form-builder.css
[error] 225-225: expected }
but instead the file ends
the file ends here
(parse)
[error] 70-70: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
🔇 Additional comments (62)
admin/form-builder/assets/js/form-builder.js (14)
71-73
: Good update for backward compatibility.This change properly handles both the new 'form-fields-v4-1' and the old 'form-fields' identifiers when resetting the editing field ID, ensuring backward compatibility during the transition.
91-107
: Formatting improvement for better readability.The spacing changes in the
open_field_settings
method improve code readability while maintaining the same functionality.
168-173
: Improved internationalization implementation.The use of
sprintf
with the WordPress i18n functions improves the structure of translated strings, making it easier for translators to work with proper sentence structure across different languages.
179-180
: Updated UI styling for better visual consistency.The modal styling has been updated with Tailwind CSS classes for better integration with the overall UI design system.
Also applies to: 184-186
242-244
: Consistent updates for the new panel identifier.Good consistency in updating the panel reset behavior across all field manipulation functions.
Also applies to: 389-391
394-401
: New panel section management methods provide better state control.These new methods improve the management of panel sections by allowing dynamic updates and resetting to defaults when needed.
420-428
: Enhanced data model for settings management.The addition of new data properties creates a more robust structure for managing form settings and UI state.
467-478
: Added computed properties for reactive settings management.These computed properties ensure the UI remains reactive to changes in the Vuex store, improving the user experience.
488-497
: Improved initialization of select dropdowns.The watch handler ensures that selectize is properly initialized whenever the settings tab changes, providing a consistent UI experience.
503-508
: Enhanced component initialization.Initializing selectize during the Vue component's created lifecycle ensures that all dropdowns have the proper styling and functionality from the start.
574-682
: New settings management methods improve user interaction.These methods provide a more structured approach to handling settings navigation and updates, making the codebase more maintainable.
🧰 Tools
🪛 Biome (1.9.4)
[error] 580-580: 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)
713-1057
: Well-structured FormDependencyHandler implementation.The FormDependencyHandler class is well-organized with clear methods for managing field dependencies based on conditions. This OOP approach improves code organization and maintainability compared to procedural code.
Some key improvements in this implementation:
- Proper initialization of dependencies
- Clear separation of concerns with distinct methods
- Event handling for different field types
- Selective field visibility based on complex conditions
1066-1105
: Enhanced category population with better UX.The
populate_default_categories
function has been improved with:
- Better handling of different post types
- Proper data persistence with the
data-value
attribute- Improved selectize initialization
However, there's an opportunity to improve error handling.
function populate_default_categories(obj) { var post_type = $(obj).val(); + const originalValue = $(obj).data('original-value'); wp.ajax.send('wpuf_form_setting_post', { data: { post_type: post_type, wpuf_form_builder_setting_nonce: wpuf_form_builder.nonce }, success: function (response) { // ... existing success handling ... }, error: function (error) { - console.log(error); + // Restore previous value + $(obj).val(originalValue); + + // Show user feedback + toastr.error(wpuf_form_builder.i18n.category_load_error || 'Failed to load categories'); + + // Log for debugging + console.error('Category loading failed:', error); } }); }
44-44
:❓ Verification inconclusive
Verify that all UI components and event handlers support the new panel identifier.
The change from 'form-fields' to 'form-fields-v4-1' indicates a version upgrade to the form fields panel. Ensure that all references to the panel ID throughout the codebase have been updated accordingly, including any templates, event handlers, or CSS selectors that may target the specific panel.
🏁 Script executed:
#!/bin/bash # Search for any remaining references to 'form-fields' that might need updating echo "Searching for potentially outdated references to 'form-fields'..." rg -A 2 -B 2 "form-fields" --type js --type vue --type php | grep -v "form-fields-v4-1"Length of output: 260
Action required: Verify panel identifier updates across components
The panel identifier has been updated from
'form-fields'
to'form-fields-v4-1'
to reflect a version upgrade. Please ensure that this change is consistently applied across all UI components, event handlers, templates, and CSS selectors. Note that our initial search flagged an error for Vue files. To cover all bases, please run the following revised script to verify that there are no outdated references in JavaScript, PHP, and Vue files:#!/bin/bash echo "Searching for potentially outdated references to 'form-fields' in js, php, and vue files..." rg -A 2 -B 2 "form-fields" --type js --type php --glob "*.vue" | grep -v "form-fields-v4-1"Manually review any output from this command to confirm that all references have been updated accordingly.
src/css/admin/form-builder.css (26)
1-3
: Tailwind CSS Directives are Properly Set UpThe file correctly imports Tailwind’s base, components, and utilities, laying a solid foundation for the new styles.
5-33
: Components Layer: Effective Use of TailwindThe custom component classes (e.g.,
.wpuf-btn-primary
,.wpuf-btn-secondary
, and.wpuf-tooltip-top
) leverage the@apply
directive effectively for a consistent design. The structure is clear and modular.
35-51
: Utilities Layer: Transition and Scaling ClassesThe defined utility classes for transitions, durations, easing, and transforms (e.g.,
.wpuf-transition-all
,.wpuf-scale-95
) are concise and well implemented.
53-55
: Container Styling for#wpcontent
A simple and effective use of a background color ensures the content container is clean and unobtrusive.
57-64
: Dropdown Transition EffectsThe transition styles for dropdown items and their container hover states provide smooth visual feedback, enhancing user interaction.
66-71
: Remove Redundant Background Property in.wpuf-pattern-1
The rule for
.wpuf-pattern-1
includes bothbackground-color: #ffffff;
and abackground
shorthand, which makes the former redundant. Consider removing thebackground-color
property to avoid conflicts.🧰 Tools
🪛 Biome (1.9.4)
[error] 70-70: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
73-76
: Selectize Control for Multi-select StylingThe background and border styles applied to the selectize control for multi-select are clear and help ensure visibility.
77-100
: Responsive Field Width AdjustmentsThe percentage-based width definitions for various field sizes (small, medium, large) are effective in maintaining a responsive layout.
101-110
: Sidebar Menu Icon StylingThe stroke color settings for sidebar menu SVG icons (including hover and active states) improve visibility and user feedback.
111-121
: Selectize Control Appearance AdjustmentsDisabling borders, shadows, and setting precise padding for selectize controls results in a clean and modern interface.
122-128
: Icon Container SetupThe styles defined for the icon container ensure that images and related content are well-contained, even during loading states.
129-131
: Loaded Icon Container BehaviorResetting the background once the icon container is marked as loaded is handled neatly, ensuring no residual styling affects the final look.
132-141
: Icon Image Styling with TransitionsAbsolute positioning, full sizing, and smooth opacity transitions for images inside the icon container result in a polished visual effect.
142-145
: Ensuring Visibility of Loaded Images and IframesThe opacity change applied to images and iframes within the loaded icon container guarantees that the content becomes fully visible in a controlled manner.
146-160
: Shimmer Effect for Loading IndicatorsThe shimmering animation defined for loading indicators is smoothly implemented using linear gradients and a keyframe animation, enhancing the UI during data load.
161-164
: Keyframes Definition for Shimmer AnimationThe keyframes for the
wpuf-shimmer
animation are correctly set up, ensuring a consistent and continuous shimmer effect.
165-167
: Disabling Shimmer on Content LoadHiding the shimmer effect as soon as the icon container is loaded prevents unnecessary animations and contributes to a clean UI.
177-185
: Webkit Range Slider Thumb StylingThe slider thumb for Webkit browsers has proper dimensions, styling, and user interaction properties.
186-192
: Firefox Range Slider Thumb StylingThe similar styling for Firefox’s range slider thumb ensures cross-browser consistency in appearance and user experience.
193-196
: Range Input Hover StateThe background styling on hover for the range input maintains a consistent look and reinforces user interactivity.
197-202
: Slider Thumb Hover Styling Across BrowsersThe hover and active state styles for the slider thumbs are consistently applied for both Webkit and Firefox, ensuring a seamless user experience.
203-205
: Table Cell Padding AdjustmentThe padding defined for cells in option field chooser tables is concise and improves overall table readability.
206-214
: Dropdown Indicator StylingUsing FontAwesome’s icon (via the content property) for the dropdown indicator is effective, and the positioning ensures a neat appearance within the selectize input.
215-218
: Active State Adjustment for Dropdown IndicatorThe modifications applied during the active state (removing top margins and borders) for the dropdown indicator ensure consistency in design during user interaction.
222-225
: Core UI Select StylingThe styles for
.wp-core-ui select
are straightforward and effective. Verify that the rule is properly closed and consider ensuring the file ends with a newline so that parsers do not misinterpret the end of the block.🧰 Tools
🪛 Biome (1.9.4)
[error] 225-225: expected
}
but instead the file endsthe file ends here
(parse)
1-226
: Overall CSS File ReviewThis new CSS file for the post form builder is well-structured and leverages Tailwind’s capabilities effectively. Aside from the minor issues noted above (redundant background property in
.wpuf-pattern-1
and the invalidfield-sizing
property), the implementation aligns well with modern CSS practices and the project’s design objectives.🧰 Tools
🪛 Biome (1.9.4)
[error] 225-225: expected
}
but instead the file endsthe file ends here
(parse)
[error] 70-70: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
assets/js/wpuf-form-builder-mixins.js (5)
24-33
: Improved error notification UI with modern styling.The error notification for duplicate fields has been enhanced with structured HTML formatting, custom styling, and an image, providing a much better user experience than the previous plain text version.
60-64
: Good addition of pro feature detection method.This method efficiently checks if a template is a pro feature when the pro version isn't active. This will help with upselling pro features in the free version of the plugin.
68-70
: Added useful computed property for consistent button styling.The
action_button_classes
computed property standardizes button styling across the form builder, following a good pattern for maintaining UI consistency.
109-139
: Added comprehensive builder class name generator.The
builder_class_names
method provides tailored Tailwind CSS classes for different input types, improving UI consistency and maintainability. This approach centralizes styling logic and makes it easier to maintain a cohesive design system.
169-175
: Added helpful global computed properties for pro version detection.These properties make it easier to conditionally render features based on whether the pro version is active, improving code maintainability and simplifying conditional rendering throughout the application.
assets/js/wpuf-form-builder.js (16)
44-44
: Updated default panel to use new panel component.The
current_panel
state property has been updated to use the new 'form-fields-v4-1' value, which indicates a migration to a newer version of the form fields panel component.
71-73
: Extended panel reset condition to include new panel.The condition now correctly handles both the old and new panel names when resetting the editing field ID, ensuring backward compatibility while supporting the new UI structure.
104-106
: Improved code readability with consistent formatting.The setTimeout call formatting has been improved, which enhances readability and consistency across the codebase.
242-242
: Updated panel references for deletion operations.Both form field and column field deletion mutations now correctly set the current panel to the new 'form-fields-v4-1' value, providing a consistent user experience when fields are deleted.
Also applies to: 389-389
394-401
: Added state management for panel sections.These new mutations provide a way to update panel sections dynamically or reset them to their default values, enhancing the flexibility of the form builder UI.
421-428
: Added new state properties for enhanced UI features.These properties support new functionality like shortcode copying, custom logo display, and improved settings management, enriching the user experience.
468-478
: Added computed properties for dynamic settings handling.These computed properties provide reactive access to settings data, improving code organization and making it easier to maintain the settings UI.
488-497
: Added initialization for select dropdowns after tab changes.This watch handler ensures that select elements are properly initialized with selectize after settings tabs change, providing a consistent interactive experience.
503-509
: Added initialization for all select dropdowns on component creation.This ensures that all dropdown elements are properly enhanced with selectize functionality when the component is created, improving the overall UI experience.
652-669
: Added comprehensive settings class name generator.Similar to the builder class names in the mixins file, this method provides tailored Tailwind CSS classes for different settings field types, maintaining UI consistency throughout the application.
671-678
: Added methods for settings menu navigation.These methods improve the user experience by providing a smoother way to navigate between different settings sections and tabs.
680-682
: Added method for handling form settings radio selections.This method provides a clean way to update form settings when a user selects a radio option, improving code organization.
713-931
: Added comprehensive field dependency configuration.This extensive configuration object defines the dependencies between different form fields, specifying when fields should be shown or hidden based on the values of other fields.
959-1057
: Implemented form dependency handler class.This well-structured class efficiently manages field dependencies, showing or hiding fields based on defined conditions. The implementation follows good OOP principles with clear separation of concerns.
1060-1064
: Migrate from jQuery to Vue patterns.Using jQuery for DOM manipulation alongside Vue can lead to inconsistencies with Vue's virtual DOM management.
Consider using Vue's event handling and class bindings:
-$('#wpuf-form-builder').on('click', '#wpuf-toggle-field-options, #wpuf-toggle-show-form, .field-buttons .fa-pencil, .ui-draggable-handle', function() { - $('#wpuf-toggle-field-options').toggleClass('hide'); - $('#wpuf-toggle-show-form').toggleClass('show'); - $('#builder-form-fields').toggleClass('show'); -}); +<template> + <div @click="toggleFieldOptions"> + <div :class="{ 'hide': isFieldOptionsHidden }">...</div> + <div :class="{ 'show': isFormShown }">...</div> + <div :class="{ 'show': isBuilderFieldsShown }">...</div> + </div> +</template> + +<script> +methods: { + toggleFieldOptions() { + this.isFieldOptionsHidden = !this.isFieldOptionsHidden; + this.isFormShown = !this.isFormShown; + this.isBuilderFieldsShown = !this.isBuilderFieldsShown; + } +} +</script>
1070-1105
: Improved post type change handler.The updated function properly handles post type changes, fetching the appropriate category options and maintaining selected values. The implementation also uses proper error handling and selectize initialization.
assets/js-templates/form-components.php (1)
577-584
: Improve accessibility for custom dropdown implementation.The custom dropdown implementation lacks proper keyboard accessibility features, making it difficult for keyboard-only users to interact with it.
Apply the following changes to make the dropdown accessible:
<p @click="showOptions = !showOptions" + @keydown.enter="showOptions = !showOptions" + @keydown.space.prevent="showOptions = !showOptions" + role="combobox" + :aria-expanded="showOptions" + tabindex="0" class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-min-w-full wpuf-rounded-md wpuf-py-1 wpuf-px-2 wpuf-text-gray-900 !wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300 wpuf-max-w-full hover:wpuf-cursor-pointer" > {{ selectedOption }} <i :class="showOptions ? 'fa-angle-up' : 'fa-angle-down'" class="fa" + aria-hidden="true" ></i> </p>
.wpuf-field-sizing-content { | ||
field-sizing: content; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Invalid CSS Property in .wpuf-field-sizing-content
The property field-sizing: content;
is not valid CSS. Replace it with a valid property (for example, box-sizing: content-box;
) if the intent is to control element sizing.
default: () => ({ key: 'value' }) | ||
}, | ||
|
||
editing_form_field: { | ||
type: Object, | ||
default: {} | ||
default: () => ({ key: 'value' }) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fixed Vue props object default values.
Similar to the earlier fix, this updates the default values for option_field
and editing_form_field
props to use functions returning objects, which is the recommended pattern for Vue.js to avoid shared references between component instances.
open_field_settings: function ( state, field_id ) { | ||
var field = state.form_fields.filter( function ( item ) { | ||
return parseInt( field_id ) === parseInt( item.id ); | ||
} ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Ensure field element access is safe.
When accessing field[0]
, make sure the field
array is not empty. If field.length === 0
, the code would attempt to access an undefined element, potentially causing errors.
🏁 Script executed:
#!/bin/bash
# Check for potential null reference issues in field access
rg -A 5 $'field\[0\]' --type js
Length of output: 3896
Action Required: Ensure Safe Access to the First Array Element in Field Handling
The code in assets/js/wpuf-form-builder.js
currently accesses field[0].id
before confirming that the field
array is non-empty. This could lead to runtime errors if the filtering produces an empty array. For example, instead of:
if ('field-options' === state.current_panel && field[0].id === state.editing_field_id) {
return;
}
it would be safer to first verify that the array has at least one element:
if ( field.length && 'field-options' === state.current_panel && field[0].id === state.editing_field_id ) {
return;
}
- Location:
assets/js/wpuf-form-builder.js
, insideopen_field_settings
- Action: Update all instances where
field[0]
is accessed without a preceding length check to ensure it only occurs whenfield.length
is truthy.
:placeholder="field.placeholder" | ||
:deault="field.default" | ||
:default="field.default" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect attribute in textarea field.
The textarea component uses :default
attribute which isn't a valid attribute for textarea elements. It should be :value
instead.
<textarea
v-if="'no' === field.rich"
:placeholder="field.placeholder"
- :default="field.default"
+ :value="field.default"
:rows="field.rows"
:cols="field.cols"
:class="builder_class_names('textareafield')">{{ field.default }}</textarea>
📝 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.
:default="field.default" | |
<textarea | |
v-if="'no' === field.rich" | |
:placeholder="field.placeholder" | |
:value="field.default" | |
:rows="field.rows" | |
:cols="field.cols" | |
:class="builder_class_names('textareafield')">{{ field.default }}</textarea> |
<div | ||
v-if="has_options" v-for="(label, val) in field.options" | ||
class="wpuf-relative wpuf-flex wpuf-items-center"> | ||
<div class="wpuf-flex wpuf-items-center"> | ||
<input | ||
type="checkbox" | ||
:value="val" | ||
:checked="is_selected(val)" | ||
:class="class_names('checkbox_btns')" | ||
> {{ label }} | ||
</label> | ||
</li> | ||
</ul> | ||
:class="builder_class_names('checkbox')"> | ||
<label class="wpuf-ml-3 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label> | ||
</div> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix label association in checkbox field.
The label and input in the checkbox field aren't properly associated, which could cause issues for screen reader users and affect usability.
<div
v-if="has_options" v-for="(label, val) in field.options"
class="wpuf-relative wpuf-flex wpuf-items-center">
<div class="wpuf-flex wpuf-items-center">
<input
type="checkbox"
:value="val"
:checked="is_selected(val)"
+ :id="'wpuf-checkbox-' + field.id + '-' + val"
:class="builder_class_names('checkbox')">
- <label class="wpuf-ml-3 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label>
+ <label :for="'wpuf-checkbox-' + field.id + '-' + val" class="wpuf-ml-3 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label>
</div>
</div>
Apply similar changes to all form elements where labels and inputs need proper association.
📝 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.
<div | |
v-if="has_options" v-for="(label, val) in field.options" | |
class="wpuf-relative wpuf-flex wpuf-items-center"> | |
<div class="wpuf-flex wpuf-items-center"> | |
<input | |
type="checkbox" | |
:value="val" | |
:checked="is_selected(val)" | |
:class="class_names('checkbox_btns')" | |
> {{ label }} | |
</label> | |
</li> | |
</ul> | |
:class="builder_class_names('checkbox')"> | |
<label class="wpuf-ml-3 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label> | |
</div> | |
</div> | |
<div | |
v-if="has_options" v-for="(label, val) in field.options" | |
class="wpuf-relative wpuf-flex wpuf-items-center"> | |
<div class="wpuf-flex wpuf-items-center"> | |
<input | |
type="checkbox" | |
:value="val" | |
:checked="is_selected(val)" | |
:id="'wpuf-checkbox-' + field.id + '-' + val" | |
:class="builder_class_names('checkbox')"> | |
<label :for="'wpuf-checkbox-' + field.id + '-' + val" class="wpuf-ml-3 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label> | |
</div> | |
</div> |
> | ||
<div class="wpuf-absolute wpuf-w-full wpuf-h-full wpuf-z-10"></div> | ||
<component |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Ensure keyboard navigation through form fields.
The absolute positioned overlay div with a z-index could block keyboard navigation through form fields, making the form inaccessible for keyboard users.
🏁 Script executed:
#!/bin/bash
# Check if there's any JavaScript code that handles tabbing or keyboard navigation for these elements
rg -B 5 -A 5 "keyboard|tab|keydown" --type js assets/js
Length of output: 67548
Accessibility Concern: Overlay May Block Keyboard Navigation
The absolute-positioned overlay div (rendered with the classes wpuf-absolute wpuf-w-full wpuf-h-full wpuf-z-10
) might intercept focus and prevent keyboard users from navigating to underlying form fields. The recent search through our JavaScript files did not reveal any code that programmatically fixes this by, for example, excluding the overlay from the tab order.
- Suggestion: Consider removing the overlay from the focus order by adding attributes like
aria-hidden="true"
and/ortabindex="-1"
, or adjust its styling (e.g. viapointer-events: none;
) so that it does not interfere with keyboard navigation. - Action: Please verify that keyboard users can access all form fields when this overlay is present.
class="wpuf-flex wpuf-items-center"> | ||
<input | ||
type="radio" | ||
:class="builder_class_names('radio')"> | ||
<label | ||
:value="val" | ||
:checked="is_selected(val)">{{ label }}</label> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix HTML structure in radio field component.
The radio button component has an invalid HTML structure with the label incorrectly positioned, which could affect accessibility and styling.
<div
v-if="has_options" v-for="(label, val) in field.options"
class="wpuf-flex wpuf-items-center">
<input
type="radio"
+ :id="'wpuf-radio-' + field.id + '-' + val"
+ :value="val"
+ :checked="is_selected(val)"
:class="builder_class_names('radio')">
- <label
- :value="val"
- :checked="is_selected(val)">{{ label }}</label>
+ <label :for="'wpuf-radio-' + field.id + '-' + val" class="wpuf-ml-2 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label>
</div>
📝 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.
class="wpuf-flex wpuf-items-center"> | |
<input | |
type="radio" | |
:class="builder_class_names('radio')"> | |
<label | |
:value="val" | |
:checked="is_selected(val)">{{ label }}</label> | |
</div> | |
<div | |
v-if="has_options" v-for="(label, val) in field.options" | |
class="wpuf-flex wpuf-items-center"> | |
<input | |
type="radio" | |
:id="'wpuf-radio-' + field.id + '-' + val" | |
:value="val" | |
:checked="is_selected(val)" | |
:class="builder_class_names('radio')"> | |
<label :for="'wpuf-radio-' + field.id + '-' + val" class="wpuf-ml-2 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label> | |
</div> |
class="field-buttons group-hover:wpuf-opacity-100 wpuf-rounded-b-lg !wpuf-bg-green-600 wpuf-items-center wpuf-transition wpuf-duration-150 wpuf-ease-out wpuf-flex wpuf-justify-around"> | ||
<div class="wpuf-flex wpuf-justify-around wpuf-text-green-200"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Ensure keyboard focus visibility for interactive elements.
The field buttons have opacity transitions that may hide them when not hovered, which could make it difficult for keyboard users to see which element is currently focused.
<div
:class="parseInt(editing_form_id) === parseInt(field.id) ? 'wpuf-opacity-100' : 'wpuf-opacity-0'"
- class="field-buttons group-hover:wpuf-opacity-100 wpuf-rounded-b-lg !wpuf-bg-green-600 wpuf-items-center wpuf-transition wpuf-duration-150 wpuf-ease-out wpuf-flex wpuf-justify-around">
+ class="field-buttons group-hover:wpuf-opacity-100 focus-within:wpuf-opacity-100 wpuf-rounded-b-lg !wpuf-bg-green-600 wpuf-items-center wpuf-transition wpuf-duration-150 wpuf-ease-out wpuf-flex wpuf-justify-around">
Apply similar changes to all interactive elements with opacity transitions for consistent keyboard navigation support.
📝 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.
class="field-buttons group-hover:wpuf-opacity-100 wpuf-rounded-b-lg !wpuf-bg-green-600 wpuf-items-center wpuf-transition wpuf-duration-150 wpuf-ease-out wpuf-flex wpuf-justify-around"> | |
<div class="wpuf-flex wpuf-justify-around wpuf-text-green-200"> | |
<div | |
:class="parseInt(editing_form_id) === parseInt(field.id) ? 'wpuf-opacity-100' : 'wpuf-opacity-0'" | |
class="field-buttons group-hover:wpuf-opacity-100 focus-within:wpuf-opacity-100 wpuf-rounded-b-lg !wpuf-bg-green-600 wpuf-items-center wpuf-transition wpuf-duration-150 wpuf-ease-out wpuf-flex wpuf-justify-around"> | |
<div class="wpuf-flex wpuf-justify-around wpuf-text-green-200"> |
<script type="text/x-template" id="tmpl-wpuf-help-text"> | ||
<i class="fa fa-question-circle field-helper-text wpuf-tooltip" :data-placement="placement" :title="text"></i> | ||
<span | ||
class="field-helper-text wpuf-ml-2" | ||
:data-placement="placement" | ||
data-toggle="tooltip" | ||
data-container="body"> | ||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none"> | ||
<path d="M9.833 12.333H9V9h-.833M9 5.667h.008M16.5 9a7.5 7.5 0 1 1-15 0 7.5 7.5 0 1 1 15 0z" | ||
stroke="#9CA3AF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path> | ||
</svg> | ||
</span> |
There was a problem hiding this comment.
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 tooltip accessibility and behavior.
The help text tooltip lacks proper semantic structure and accessibility attributes, making it difficult for screen readers to interpret.
<span
class="field-helper-text wpuf-ml-2"
:data-placement="placement"
- data-toggle="tooltip"
- data-container="body">
+ data-toggle="tooltip"
+ data-container="body"
+ role="tooltip"
+ tabindex="0"
+ aria-label="Help information">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none"
+ aria-hidden="true"
+ focusable="false">
<path d="M9.833 12.333H9V9h-.833M9 5.667h.008M16.5 9a7.5 7.5 0 1 1-15 0 7.5 7.5 0 1 1 15 0z"
stroke="#9CA3AF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</span>
📝 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.
<script type="text/x-template" id="tmpl-wpuf-help-text"> | |
<i class="fa fa-question-circle field-helper-text wpuf-tooltip" :data-placement="placement" :title="text"></i> | |
<span | |
class="field-helper-text wpuf-ml-2" | |
:data-placement="placement" | |
data-toggle="tooltip" | |
data-container="body"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none"> | |
<path d="M9.833 12.333H9V9h-.833M9 5.667h.008M16.5 9a7.5 7.5 0 1 1-15 0 7.5 7.5 0 1 1 15 0z" | |
stroke="#9CA3AF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path> | |
</svg> | |
</span> | |
<script type="text/x-template" id="tmpl-wpuf-help-text"> | |
<span | |
class="field-helper-text wpuf-ml-2" | |
:data-placement="placement" | |
data-toggle="tooltip" | |
data-container="body" | |
role="tooltip" | |
tabindex="0" | |
aria-label="Help information"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" | |
aria-hidden="true" | |
focusable="false"> | |
<path d="M9.833 12.333H9V9h-.833M9 5.667h.008M16.5 9a7.5 7.5 0 1 1-15 0 7.5 7.5 0 1 1 15 0z" | |
stroke="#9CA3AF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path> | |
</svg> | |
</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🔭 Outside diff range comments (1)
admin/form-builder/views/post-form-settings.php (1)
283-603
: 🛠️ Refactor suggestionBreak down the large rendering function.
wpuf_render_settings_field
handles multiple field types in one place, which is powerful but quite lengthy. Extract smaller helper functions for toggles, color pickers, etc., to improve readability and maintainability.
♻️ Duplicate comments (1)
Gruntfile.js (1)
287-303
:⚠️ Potential issueAdd error handling to the tailwind task.
The current implementation of the tailwind task lacks error handling for file operations and shell command execution. This can lead to silent failures and make debugging difficult.
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)) { + try { + if (!grunt.file.exists(inputFile)) { + grunt.log.error(`Input file ${inputFile} does not exist`); + hasErrors = true; + return; + } + + // Ensure the output directory exists + const outputDir = require('path').dirname(outputFile); + if (!grunt.file.exists(outputDir)) { + grunt.file.mkdir(outputDir); + } + // Run the tailwind command grunt.task.run(`shell:tailwind:${inputFile}:${outputFile}`); + } catch (error) { + grunt.log.error(`Error processing ${inputFile}: ${error.message}`); + hasErrors = true; } }); - done(); + done(!hasErrors); });
🧹 Nitpick comments (8)
wpuf-functions.php (2)
4844-4909
: Well-structured settings menu titles with consistent design.This function creates a clear organizational structure for the post form builder settings with appropriate icons and labels. The SVG icons are well-formatted and the filter hooks allow for extensibility.
Consider adding PHPDoc comments with
@since
tags to help document when these functions were introduced.
4911-5399
: Comprehensive settings menu content implementation.This function provides a detailed and well-organized structure for form builder settings with appropriate default values, help text, and field types. The implementation follows WordPress best practices with filters for extensibility.
Key improvements:
- Logical organization of settings into contextual sections
- Detailed help text for improved user experience
- Appropriate default values
- Filter hooks for extensibility
Consider breaking down this large function into smaller, more manageable functions for each section (general, payment, notification, etc.) to improve maintainability. For example:
function wpuf_get_post_form_builder_setting_menu_contents() { return apply_filters( 'wpuf_post_form_builder_setting_menu_contents', [ 'post_settings' => [ 'general' => wpuf_get_form_builder_general_settings(), 'payment_settings' => wpuf_get_form_builder_payment_settings(), 'notification_settings' => wpuf_get_form_builder_notification_settings(), 'display_settings' => wpuf_get_form_builder_display_settings(), 'advanced' => wpuf_get_form_builder_advanced_settings(), 'post_expiration' => wpuf_get_form_builder_post_expiration_settings(), ] ] ); }Gruntfile.js (2)
3-6
: Consider adding additional tailwind configuration files.The
tailwindFileMap
provides a mapping between PHP files and corresponding CSS files, which is good for maintaining structure. However, it might be beneficial to extract this mapping to a separate configuration file for better maintainability as the project grows, especially if you plan to add more mappings in the future.- const tailwindFileMap = { - 'admin/form-builder/views/form-builder-v4.1.php': 'admin/form-builder.css', - 'admin/form-builder/views/post-form-settings.php': 'admin/form-builder.css', - } + // Import the tailwind mapping from a separate configuration file + const tailwindFileMap = require('./tailwind-config.js');
122-135
: Improve watch configuration for tailwind.The watch configuration for tailwind is monitoring a broad set of files including CSS, PHP, and JS files. This can lead to unnecessary rebuilds when unrelated files change. Consider making the file patterns more specific to only watch files that directly affect tailwind styles.
tailwind: { files: [ - 'src/css/**/*.css', - 'admin/form-builder/views/*.php', - 'admin/form-builder/assets/js/**/*.php', - 'admin/form-builder/assets/js/**/*.js', - 'includes/Admin/**/*.php', - 'wpuf-functions.php', + // Only watch CSS files and PHP templates that contain tailwind classes + 'src/css/**/*.css', + 'admin/form-builder/views/form-builder-v4.1.php', + 'admin/form-builder/views/post-form-settings.php', ], tasks: ['shell:tailwind:src/css/admin/form-builder.css:assets/css/admin/form-builder.css'], options: { spawn: false } },includes/Admin/Forms/Admin_Form.php (1)
197-219
: Enhanced UI with Vue.js conditional rendering for tab contents.The form settings UI has been improved by replacing static tabs with Vue.js
v-show
directives. This approach is more maintainable and provides a better UX by keeping the DOM complete but only showing relevant sections.Consider adding transition effects for tab switching to enhance the user experience:
-<div v-show="active_settings_tab === '#wpuf-metabox-settings'" id="wpuf-metabox-settings" class="group"> +<div v-show="active_settings_tab === '#wpuf-metabox-settings'" + id="wpuf-metabox-settings" + class="group wpuf-transition-opacity wpuf-duration-300">includes/Admin/Forms/Admin_Form_Builder.php (1)
297-326
: Improve i18n string handling for better internationalization.The localization implementation has been updated to include new strings, but it could be improved further to enhance maintainability and translation quality.
private function i18n() { $crown_icon = WPUF_ASSET_URI . '/images/crown-white.svg'; $field_messages = $this->get_pro_field_messages(); + // Define translatable strings separately for better organization + $strings = [ + 'advanced_options' => __( 'Advanced Options', 'wp-user-frontend' ), + 'delete_field_warn_msg' => __( 'Are you sure you want to delete this field?', 'wp-user-frontend' ), + 'yes_delete_it' => __( 'Yes, delete it', 'wp-user-frontend' ), + 'no_cancel_it' => __( 'No, cancel it', 'wp-user-frontend' ), + 'ok' => __( 'Okay', 'wp-user-frontend' ), + 'cancel' => __( 'Cancel', 'wp-user-frontend' ), + 'close' => __( 'Close', 'wp-user-frontend' ), + 'last_choice_warn_msg' => __( 'This field must contain at least one choice', 'wp-user-frontend' ), + 'option' => __( 'Option', 'wp-user-frontend' ), + 'column' => __( 'Column', 'wp-user-frontend' ), + 'last_column_warn_msg' => __( 'This field must contain at least one column', 'wp-user-frontend' ), + 'is_a_pro_feature' => __( 'is a pro feature', 'wp-user-frontend' ), + 'select' => __( 'Select', 'wp-user-frontend' ), + 'saved_form_data' => __( 'Saved form data', 'wp-user-frontend' ), + 'unsaved_changes' => __( 'You have unsaved changes.', 'wp-user-frontend' ), + 'copy_shortcode' => __( 'Click to copy shortcode', 'wp-user-frontend' ), + ]; + + // Define HTML content separately to make translations easier + $strings['pro_feature_msg'] = __( + '<p class="wpuf-text-gray-500 wpuf-font-medium wpuf-text-xl">Please upgrade to the Pro version to unlock all these awesome features</p>', + 'wp-user-frontend' + ); + + // Create upgrade button with icon + $strings['upgrade_to_pro'] = sprintf( + __( 'Upgrade to PRO %s', 'wp-user-frontend' ), + '<img src="' . esc_url( $crown_icon ) . '"/>' + ); + + // Add pro field messages + $strings['pro_field_message'] = $field_messages; + + return apply_filters( 'wpuf_form_builder_i18n', $strings ); - return apply_filters( - 'wpuf_form_builder_i18n', [ - 'advanced_options' => __( 'Advanced Options', 'wp-user-frontend' ), - 'delete_field_warn_msg' => __( 'Are you sure you want to delete this field?', 'wp-user-frontend' ), - 'yes_delete_it' => __( 'Yes, delete it', 'wp-user-frontend' ), - 'no_cancel_it' => __( 'No, cancel it', 'wp-user-frontend' ), - 'ok' => __( 'Okay', 'wp-user-frontend' ), - 'cancel' => __( 'Cancel', 'wp-user-frontend' ), - 'close' => __( 'Close', 'wp-user-frontend' ), - 'last_choice_warn_msg' => __( 'This field must contain at least one choice', 'wp-user-frontend' ), - 'option' => __( 'Option', 'wp-user-frontend' ), - 'column' => __( 'Column', 'wp-user-frontend' ), - 'last_column_warn_msg' => __( 'This field must contain at least one column', 'wp-user-frontend' ), - 'is_a_pro_feature' => __( 'is a pro feature', 'wp-user-frontend' ), - 'pro_feature_msg' => __( - '<p class="wpuf-text-gray-500 wpuf-font-medium wpuf-text-xl">Please upgrade to the Pro version to unlock all these awesome features</p>', - 'wp-user-frontend' - ), - 'upgrade_to_pro' => sprintf( - __( 'Upgrade to PRO %s', 'wp-user-frontend' ), '<img src="' . $crown_icon . '"/>' - ), - 'select' => __( 'Select', 'wp-user-frontend' ), - 'saved_form_data' => __( 'Saved form data', 'wp-user-frontend' ), - 'unsaved_changes' => __( 'You have unsaved changes.', 'wp-user-frontend' ), - 'copy_shortcode' => __( 'Click to copy shortcode', 'wp-user-frontend' ), - 'pro_field_message' => $field_messages, - ] - ); }admin/form-builder/views/post-form-settings.php (1)
109-190
: Consider performance in nested loops.This code loops through
$settings_items
and$section['fields']
, plus potential subloops for pro previews. While likely fine for typical usage, ensure performance remains acceptable with large sets of settings.admin/form-builder/assets/js/form-builder.js (1)
580-580
: Simplify the boolean toggle.Use logical negation instead of the ternary for cleaner code.
- this.is_form_switcher = (this.is_form_switcher) ? false : true; + this.is_form_switcher = !this.is_form_switcher;🧰 Tools
🪛 Biome (1.9.4)
[error] 580-580: 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)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
Gruntfile.js
(5 hunks)admin/form-builder/assets/js/form-builder.js
(14 hunks)admin/form-builder/views/form-builder-v4.1.php
(1 hunks)admin/form-builder/views/post-form-settings.php
(1 hunks)assets/js/wpuf-form-builder.js
(14 hunks)includes/Admin/Forms/Admin_Form.php
(3 hunks)includes/Admin/Forms/Admin_Form_Builder.php
(7 hunks)wpuf-functions.php
(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- admin/form-builder/views/form-builder-v4.1.php
🧰 Additional context used
🪛 Biome (1.9.4)
admin/form-builder/assets/js/form-builder.js
[error] 580-580: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
assets/js/wpuf-form-builder.js
[error] 580-580: 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)
🔇 Additional comments (24)
wpuf-functions.php (5)
2938-2938
: Improved message format with dynamic placeholders.The message format now uses
{login}
and{register}
placeholders instead of a static string, allowing dynamic content insertion for better user experience.
4822-4831
: New utility function to get Pro icon URL.Well-implemented function that centralizes the path to the Pro icon, making it easier to maintain and update across the codebase.
4833-4842
: Clean implementation of Pro version detection.This function provides a simple way to check if the Pro version is active, following best practices by checking for the existence of the main Pro class.
987-987
: Fixed conditional check for field rendering.The condition now properly checks if the
$wpuf_field
object exists and has the required method before calling it, preventing potential PHP errors.
62-63
: Improved variable initialization for admin post status.The code now initializes variables for
$fontcolor
and$title
with default values, which is good practice to prevent undefined variable notices.includes/Admin/Forms/Admin_Form.php (2)
157-158
: LGTM! Modified hook for settings tabs.The hook name has been updated to
wpuf_form_builder_settings_tabs_post
which aligns better with the updated Vue.js implementation of the form builder.
234-239
:✅ Verification successful
Simplified settings tab inclusion.
The previous implementation has been refactored to use a more direct approach for including the settings file. This is cleaner and avoids unnecessary function calls.
Let's check if the settings file exists:
🏁 Script executed:
#!/bin/bash # Check if the post-form-settings.php file exists if [ -f "admin/form-builder/views/post-form-settings.php" ]; then echo "✅ File exists: admin/form-builder/views/post-form-settings.php" else echo "❌ File not found: admin/form-builder/views/post-form-settings.php" # Check if there are any files with similar names find admin/form-builder/views -name "*settings*.php" -type f fiLength of output: 195
Simplified Settings Inclusion Confirmed
The direct inclusion in
includes/Admin/Forms/Admin_Form.php
has been refactored as intended. We verified thatadmin/form-builder/views/post-form-settings.php
exists in the expected location, confirming that the cleaner approach is valid and no redundant function calls remain.
- Location:
includes/Admin/Forms/Admin_Form.php
(Lines 234-239)- Verification: The settings file exists at
admin/form-builder/views/post-form-settings.php
No further modifications are required.
includes/Admin/Forms/Admin_Form_Builder.php (2)
59-59
: Added new action hook for form builder view.The added action hook
wpuf_admin_form_builder_view
provides more flexibility for plugins to inject content into the form builder UI. This is a good improvement for extensibility.
279-286
: Updated form builder view to use newer template.The form builder now uses the enhanced v4.1 template, which aligns with the UI improvements introduced throughout this PR. The code also now fetches forms dynamically with proper parameters.
admin/form-builder/views/post-form-settings.php (7)
1-37
: Ensure responsiveness for new settings container.The layout classes look consistent, but consider testing the UI at various screen sizes to confirm the sidebar and content area are equally usable on smaller viewports.
39-53
: Visual hierarchy appears well-structured.Your heading and label arrangement is straightforward and consistent. No immediate issues found.
55-93
: Consistent naming of nested menus is good.Your
.wpuf-sidebar-menu
and sub-list elements follow a clear naming approach, making the code more readable.
96-98
: No substantive changes.This snippet only separates PHP tags. There’s nothing to address.
106-108
: Settings retrieval confirmed.Retrieving form settings using
$post->ID
is correct. No issues spotted, assuming$post->ID
is always defined here.
191-260
: Graceful fallback for inactive modules.Showing an illustrative SVG and a call-to-action button provides helpful user feedback when modules are not active. Good job.
264-280
: Double-check user flow on cancel.The Cancel button presumably returns or closes without saving changes. Confirm you’re prompting users if unsaved settings might be lost.
admin/form-builder/assets/js/form-builder.js (5)
44-45
: Default to 'form-fields-v4-1' looks good.Setting the initial
current_panel
to'form-fields-v4-1'
modernizes the UI workflow.
71-74
: Resetting editing_field_id conditionally.Clearing
editing_field_id
whenever the panel is'form-fields'
or'form-fields-v4-1'
is consistent with your logic flow.
91-94
: Avoid potential empty-array access.Accessing
field[0].id
can throw an error iffield
is an empty array. Checkfield.length
before referencingfield[0]
.
389-389
: Panel sections logic is tidy.Adding and resetting panel sections via
set_panel_sections
andset_default_panel_sections
is straightforward. No issues spotted.Also applies to: 394-396, 400-401
585-587
: Use a Vuex mutation for reactivity.Directly reassigning
this.$store.state.panel_sections
bypasses Vuex best practices. Prefer committing a mutation (e.g.,set_panel_sections
) for reactive state changes.assets/js/wpuf-form-builder.js (3)
580-580
: Unnecessary boolean ternary usage.Please invert the value with
!
, aligning with typical JavaScript patterns.🧰 Tools
🪛 Biome (1.9.4)
[error] 580-580: 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)
585-587
: Recommend using store mutation for consistency.Assigning to
this.$store.state.panel_sections
directly occurs outside a mutation, possibly breaking Vuex patterns.
1064-1068
: Migrate from jQuery toggle to Vue event handling.You are mixing jQuery toggles with Vue for the same UI elements. This can cause synchronization issues.
tailwind: { | ||
command: function ( input, output ) { | ||
return `npx tailwindcss -i ${input} -o ${output}`; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add validation for Tailwind CLI input and output paths.
The current implementation doesn't validate the input and output paths before executing the Tailwind CLI command. This could lead to errors if the paths contain spaces or special characters.
tailwind: {
command: function ( input, output ) {
- return `npx tailwindcss -i ${input} -o ${output}`;
+ // Validate and sanitize input and output paths
+ const sanitizedInput = input.replace(/[^a-zA-Z0-9/\-_.]/g, '');
+ const sanitizedOutput = output.replace(/[^a-zA-Z0-9/\-_.]/g, '');
+
+ if (sanitizedInput !== input || sanitizedOutput !== output) {
+ grunt.log.warn('Input or output paths contain invalid characters and were sanitized.');
+ }
+
+ return `npx tailwindcss -i "${sanitizedInput}" -o "${sanitizedOutput}"`;
}
}
📝 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.
tailwind: { | |
command: function ( input, output ) { | |
return `npx tailwindcss -i ${input} -o ${output}`; | |
} | |
} | |
tailwind: { | |
command: function ( input, output ) { | |
// Validate and sanitize input and output paths | |
const sanitizedInput = input.replace(/[^a-zA-Z0-9/\-_.]/g, ''); | |
const sanitizedOutput = output.replace(/[^a-zA-Z0-9/\-_.]/g, ''); | |
if (sanitizedInput !== input || sanitizedOutput !== output) { | |
grunt.log.warn('Input or output paths contain invalid characters and were sanitized.'); | |
} | |
return `npx tailwindcss -i "${sanitizedInput}" -o "${sanitizedOutput}"`; | |
} | |
} |
/** | ||
* Transient key to store pro field assets info | ||
* | ||
* @since WPUF_SINCE | ||
* | ||
* @var string | ||
*/ | ||
const PRO_FIELD_ASSETS = 'wpuf_pro_field_assets'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Properly document the PRO_FIELD_ASSETS constant.
The constant is missing a proper version tag. The placeholder WPUF_SINCE
should be replaced with the actual version number where this constant was introduced.
/**
* Transient key to store pro field assets info
*
*
- * @since WPUF_SINCE
+ * @since 3.5.0
*
* @var string
*/
const PRO_FIELD_ASSETS = 'wpuf_pro_field_assets';
📝 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.
/** | |
* Transient key to store pro field assets info | |
* | |
* @since WPUF_SINCE | |
* | |
* @var string | |
*/ | |
const PRO_FIELD_ASSETS = 'wpuf_pro_field_assets'; | |
/** | |
* Transient key to store pro field assets info | |
* | |
* @since 3.5.0 | |
* | |
* @var string | |
*/ | |
const PRO_FIELD_ASSETS = 'wpuf_pro_field_assets'; |
/** | ||
* Check and get pro-field related text, image, video etc. to show when user clicks on a pro field | ||
* | ||
* @since WPUF_SINCE | ||
* | ||
* @return array | ||
*/ | ||
protected function get_pro_field_messages() { | ||
$info = get_transient( self::PRO_FIELD_ASSETS ); | ||
|
||
if ( false === $info ) { | ||
$url = 'https://raw.githubusercontent.com/weDevsOfficial/wpuf-util/master/pro-field-assets.json'; | ||
$response = wp_remote_get( $url, [ 'timeout' => 15 ] ); | ||
$info = wp_remote_retrieve_body( $response ); | ||
|
||
if ( is_wp_error( $response ) || ( 200 !== $response['response']['code'] ) ) { | ||
return []; | ||
} | ||
|
||
set_transient( self::PRO_FIELD_ASSETS, $info, DAY_IN_SECONDS ); | ||
} | ||
|
||
$info = json_decode( $info, true ); | ||
|
||
if ( empty( $info ) ) { | ||
return []; | ||
} | ||
|
||
return $info; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implement better error handling and caching in get_pro_field_messages.
The current implementation has potential issues with error handling, security, and caching. It fetches data from an external URL without proper validation and assumes the response will be in a specific format.
protected function get_pro_field_messages() {
$info = get_transient( self::PRO_FIELD_ASSETS );
if ( false === $info ) {
$url = 'https://raw.githubusercontent.com/weDevsOfficial/wpuf-util/master/pro-field-assets.json';
- $response = wp_remote_get( $url, [ 'timeout' => 15 ] );
- $info = wp_remote_retrieve_body( $response );
+ $response = wp_remote_get(
+ $url,
+ [
+ 'timeout' => 15,
+ 'headers' => [
+ 'Accept' => 'application/json',
+ ]
+ ]
+ );
if ( is_wp_error( $response ) || ( 200 !== $response['response']['code'] ) ) {
- return [];
+ // Log the error for debugging
+ error_log( sprintf( 'WPUF: Failed to fetch pro field messages. Error: %s',
+ is_wp_error( $response ) ? $response->get_error_message() : $response['response']['message'] ) );
+
+ // Return empty array with proper format to avoid errors
+ return [
+ 'messages' => [],
+ 'images' => [],
+ 'videos' => []
+ ];
}
+
+ $info = wp_remote_retrieve_body( $response );
+
+ // Verify the response is valid JSON
+ $decoded = json_decode( $info, true );
+ if ( json_last_error() !== JSON_ERROR_NONE ) {
+ error_log( 'WPUF: Invalid JSON response for pro field messages' );
+ return [
+ 'messages' => [],
+ 'images' => [],
+ 'videos' => []
+ ];
+ }
- set_transient( self::PRO_FIELD_ASSETS, $info, DAY_IN_SECONDS );
+ // Cache for one day, but allow filtering the duration
+ $cache_duration = apply_filters( 'wpuf_pro_field_assets_cache_duration', DAY_IN_SECONDS );
+ set_transient( self::PRO_FIELD_ASSETS, $info, $cache_duration );
}
$info = json_decode( $info, true );
if ( empty( $info ) ) {
- return [];
+ return [
+ 'messages' => [],
+ 'images' => [],
+ 'videos' => []
+ ];
}
+ // Filter the response for security
+ $allowed_keys = [ 'messages', 'images', 'videos' ];
+ $filtered_info = array_intersect_key( $info, array_flip( $allowed_keys ) );
+
+ return $filtered_info;
- return $info;
}
📝 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.
/** | |
* Check and get pro-field related text, image, video etc. to show when user clicks on a pro field | |
* | |
* @since WPUF_SINCE | |
* | |
* @return array | |
*/ | |
protected function get_pro_field_messages() { | |
$info = get_transient( self::PRO_FIELD_ASSETS ); | |
if ( false === $info ) { | |
$url = 'https://raw.githubusercontent.com/weDevsOfficial/wpuf-util/master/pro-field-assets.json'; | |
$response = wp_remote_get( $url, [ 'timeout' => 15 ] ); | |
$info = wp_remote_retrieve_body( $response ); | |
if ( is_wp_error( $response ) || ( 200 !== $response['response']['code'] ) ) { | |
return []; | |
} | |
set_transient( self::PRO_FIELD_ASSETS, $info, DAY_IN_SECONDS ); | |
} | |
$info = json_decode( $info, true ); | |
if ( empty( $info ) ) { | |
return []; | |
} | |
return $info; | |
} | |
/** | |
* Check and get pro-field related text, image, video etc. to show when user clicks on a pro field | |
* | |
* @since WPUF_SINCE | |
* | |
* @return array | |
*/ | |
protected function get_pro_field_messages() { | |
$info = get_transient( self::PRO_FIELD_ASSETS ); | |
if ( false === $info ) { | |
$url = 'https://raw.githubusercontent.com/weDevsOfficial/wpuf-util/master/pro-field-assets.json'; | |
$response = wp_remote_get( | |
$url, | |
[ | |
'timeout' => 15, | |
'headers' => [ | |
'Accept' => 'application/json', | |
] | |
] | |
); | |
if ( is_wp_error( $response ) || ( 200 !== $response['response']['code'] ) ) { | |
// Log the error for debugging | |
error_log( sprintf( 'WPUF: Failed to fetch pro field messages. Error: %s', | |
is_wp_error( $response ) ? $response->get_error_message() : $response['response']['message'] ) ); | |
// Return empty array with proper format to avoid errors | |
return [ | |
'messages' => [], | |
'images' => [], | |
'videos' => [] | |
]; | |
} | |
$info = wp_remote_retrieve_body( $response ); | |
// Verify the response is valid JSON | |
$decoded = json_decode( $info, true ); | |
if ( json_last_error() !== JSON_ERROR_NONE ) { | |
error_log( 'WPUF: Invalid JSON response for pro field messages' ); | |
return [ | |
'messages' => [], | |
'images' => [], | |
'videos' => [] | |
]; | |
} | |
// Cache for one day, but allow filtering the duration | |
$cache_duration = apply_filters( 'wpuf_pro_field_assets_cache_duration', DAY_IN_SECONDS ); | |
set_transient( self::PRO_FIELD_ASSETS, $info, $cache_duration ); | |
} | |
$info = json_decode( $info, true ); | |
if ( empty( $info ) ) { | |
return [ | |
'messages' => [], | |
'images' => [], | |
'videos' => [] | |
]; | |
} | |
// Filter the response for security | |
$allowed_keys = [ 'messages', 'images', 'videos' ]; | |
$filtered_info = array_intersect_key( $info, array_flip( $allowed_keys ) ); | |
return $filtered_info; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
♻️ Duplicate comments (2)
assets/js/wpuf-form-builder.js (1)
585-588
:⚠️ Potential issueUse store mutations instead of direct state assignment.
Direct modification of Vuex store state bypasses reactivity system and breaks the single source of truth pattern. You've already created the
set_default_panel_sections
mutation for this purpose - use it.Replace the direct state assignment with a mutation:
if (panel === 'form-fields-v4-1') { - this.$store.state.panel_sections = wpuf_form_builder.panel_sections; + this.$store.commit('set_default_panel_sections'); }src/css/admin/form-builder.css (1)
213-215
: 🛠️ Refactor suggestion
⚠️ Potential issueInvalid CSS Property: Replace
field-sizing
with a Valid Property
The propertyfield-sizing: content;
is invalid. If the intent is to manage the element's sizing model, consider using a valid property such asbox-sizing: content-box;
.- field-sizing: content; + box-sizing: content-box;
🧹 Nitpick comments (11)
assets/js/wpuf-form-builder.js (3)
580-581
: Simplify boolean toggle logic.The ternary expression for toggling boolean value is unnecessarily complex and can be simplified.
-this.is_form_switcher = (this.is_form_switcher) ? false : true; +this.is_form_switcher = !this.is_form_switcher;🧰 Tools
🪛 Biome (1.9.4)
[error] 580-580: 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)
491-496
: Add error handling for asynchronous operations.The setTimeout function without proper error handling might lead to unpredictable behavior if the DOM has changed during the delay.
Consider adding checks to ensure elements still exist before operating on them:
setTimeout(function() { + if ($('.wpuf-settings-container select').length) { $('.wpuf-settings-container select').selectize({ plugins: ['remove_button'], }); + } }, 100);
1075-1114
: Implement error handling for AJAX category population.The
populate_default_categories
function makes an AJAX call to fetch categories but lacks comprehensive error handling.Add more informative error handling and loading indicators:
function populate_default_categories(obj) { var post_type = $(obj).val(); + const container = $('select#post_type').parent('.wpuf-my-4.wpuf-input-container'); + + // Add loading indicator + container.after('<div id="category-loading" class="wpuf-my-2">Loading categories...</div>'); wp.ajax.send('wpuf_form_setting_post', { data: { post_type: post_type, wpuf_form_builder_setting_nonce: wpuf_form_builder.nonce }, success: function (response) { + // Remove loading indicator + $('#category-loading').remove(); const default_category = 'select#default_category'; // Rest of code... }, error: function (error) { - console.log(error); + $('#category-loading').remove(); + container.after('<div class="wpuf-error wpuf-my-2">Failed to load categories: ' + + (error.message || 'Unknown error') + '</div>'); + // Log detailed error for debugging + console.error('Category loading error:', error); } }); }admin/form-builder/views/post-form-settings.php (4)
244-245
: Fix duplicated text in the no modules message.Both paragraphs contain the exact same text: "No modules have been activated yet." This appears to be a copy-paste error - the second paragraph should likely contain different text, perhaps providing further instructions or explanation.
<p class="wpuf-text-lg wpuf-text-gray-800 wpuf-mt-9 wpuf-mb-0">No modules have been activated yet.</p> -<p class="wpuf-text-sm wpuf-text-gray-500 wpuf-mt-2">No modules have been activated yet.</p> +<p class="wpuf-text-sm wpuf-text-gray-500 wpuf-mt-2">Activate modules to enhance your form functionality.</p>
28-34
: Improve code structure for better readability.The HTML structure around echoed content has excessive whitespace and line breaks. Consider consolidating these sections for better code readability.
<span class="wpuf-ml-2"> - <?php - echo $label; - ?> + <?php echo esc_html($label); ?> </span>Also applies to: 41-47, 71-77
105-107
: Add error handling for form settings retrieval.The code retrieves form settings without checking if the operation was successful. Consider adding error checking to handle cases where settings might not be available.
global $post; $form_settings = wpuf_get_form_settings( $post->ID ); +// Check if form settings retrieval was successful +if ( false === $form_settings ) { + $form_settings = array(); + // Optionally add error notice + echo '<div class="notice notice-error"><p>' . esc_html__( 'Error retrieving form settings.', 'wp-user-frontend' ) . '</p></div>'; +} $form_post_type = ! empty( $form_settings['post_type'] ) ? $form_settings['post_type'] : 'post';
312-313
: Enhance security for checkbox values.When checking if a checkbox is checked, the code compares with 'on' without validation. Consider adding validation to ensure input values are as expected.
<?php -echo esc_attr( checked( $value, 'on', false ) ); +echo esc_attr( checked( sanitize_text_field($value), 'on', false ) ); ?>Also applies to: 350-351, 456-457
src/css/admin/form-builder.css (1)
162-170
: Range Input Styling: Semicolon Consistency
The styling forinput[type="range"]
is well defined. For consistency and to avoid potential parsing issues, consider adding a semicolon afterborder-radius: 10px
on line 169.admin/form-builder/assets/js/form-builder.js (3)
503-508
: Repeatedselectize
calls
Consider extracting this initialization into a single reusable function or mixin to reduce duplication.
651-669
:setting_class_names
switch
Mapping field types to CSS classes is neatly organized. You might consider a dictionary/object for better scalability.
696-702
: Commented-out code
IfresizeBuilderContainer
is no longer relevant, consider removing it to keep the code clean.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
admin/form-builder/assets/js/form-builder.js
(14 hunks)admin/form-builder/views/post-form-settings.php
(1 hunks)assets/js/wpuf-form-builder.js
(14 hunks)src/css/admin/form-builder.css
(1 hunks)wpuf-functions.php
(4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
assets/js/wpuf-form-builder.js
[error] 580-580: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
admin/form-builder/assets/js/form-builder.js
[error] 580-580: 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)
src/css/admin/form-builder.css
[error] 258-258: expected }
but instead the file ends
the file ends here
(parse)
[error] 67-67: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
🔇 Additional comments (68)
wpuf-functions.php (6)
61-63
: Code improvement with variable initialization.The variables
$fontcolor
and$title
are now properly initialized before the conditional checks. This is a good coding practice that prevents potential undefined variable warnings.
987-988
: Good defensive programming addition.The added check for
! empty( $wpuf_field )
prevents a potential PHP error when attempting to call a method on a non-existent object. This improves the robustness of the code.
4822-4831
: New utility function to get the pro icon.This function provides a centralized way to retrieve the pro icon URL, improving code maintainability.
4833-4842
: Added helper function to check pro version status.The
wpuf_is_pro_active()
function provides a clean way to check if the pro version is active throughout the codebase. This is more maintainable than repeating the class_exists check everywhere.
4844-4913
: New function for post form builder menu titles.This well-structured function provides the menu titles and icons for the post form builder settings. The SVG icons are included inline which eliminates the need for additional HTTP requests, improving performance.
4915-5413
: Comprehensive implementation of form builder settings configuration.This function creates a detailed structure for all the post form builder settings. It's well-organized into logical sections (general, payment, notification, display, advanced, post expiration) and includes:
- Descriptive labels
- Help texts
- Default values
- Input types
- Options for select fields
The code also properly implements filter hooks allowing for extensibility.
One suggestion to consider: The function is quite large (nearly 500 lines). In future refactoring, you might consider breaking it down into smaller, more focused functions for each settings section to improve maintainability.
assets/js/wpuf-form-builder.js (7)
91-107
:⚠️ Potential issueFix potential null reference in the field settings panel transition.
Line 96 directly accesses
field[0].id
without first checking if the array has elements, which could lead to runtime errors. While line 100 does have a proper check, the initial reference doesn't.Apply this fix:
- if ('field-options' === state.current_panel && field[0].id === state.editing_field_id) { + if ('field-options' === state.current_panel && field.length && field[0].id === state.editing_field_id) { return; }
652-669
: Well-structured utility method for consistent styling across form elements.The
setting_class_names
method provides a centralized way to manage Tailwind CSS classes for different field types, which improves maintainability and consistency.
713-931
: Comprehensive dependency configuration object for form fields.This well-structured configuration defines the dependencies between form fields and their visibility conditions, which will make the form more dynamic and user-friendly.
963-1064
: Well-implemented FormDependencyHandler class with OOP principles.The class provides a clean implementation for managing field dependencies with proper separation of concerns. The methods are well-named and follow single responsibility principle.
Consider adding some defensive programming:
- Error handling for when fields don't exist in the DOM
- Debouncing the change event handlers to prevent performance issues with rapid changes
- A public method to refresh dependencies when form fields are dynamically added
1069-1073
: Consider migrating jQuery DOM manipulation to Vue patterns.The code still relies on jQuery for DOM manipulation alongside Vue, which can lead to inconsistencies with Vue's virtual DOM management.
While not critical, consider gradually migrating to Vue's reactivity system:
-$('#wpuf-form-builder').on('click', '#wpuf-toggle-field-options, #wpuf-toggle-show-form, .field-buttons .fa-pencil, .ui-draggable-handle', function() { - $('#wpuf-toggle-field-options').toggleClass('hide'); - $('#wpuf-toggle-show-form').toggleClass('show'); - $('#builder-form-fields').toggleClass('show'); -}); +// In Vue component data +data: { + // Add these properties + isFieldOptionsHidden: false, + isFormShown: false, + isBuilderFieldsShown: false, +}, + +// In methods +methods: { + toggleFieldOptions() { + this.isFieldOptionsHidden = !this.isFieldOptionsHidden; + this.isFormShown = !this.isFormShown; + this.isBuilderFieldsShown = !this.isBuilderFieldsShown; + } +} + +// In mounted hook +mounted() { + // Add event listener using Vue's approach + const elements = this.$el.querySelectorAll('#wpuf-toggle-field-options, #wpuf-toggle-show-form, .field-buttons .fa-pencil, .ui-draggable-handle'); + elements.forEach(el => { + el.addEventListener('click', this.toggleFieldOptions); + }); +}
179-187
:✅ Verification successful
Use consistent UI styling and ensure image is correctly loaded.
The code now uses a lock icon from the
wpuf_form_builder.lock_icon
property and applies Tailwind CSS classes for styling.However, verify that the
lock_icon
path is correctly defined in the wpuf_form_builder object to prevent broken images.
🏁 Script executed:
#!/bin/bash # Check for the definition of lock_icon in the wpuf_form_builder object rg "lock_icon" --type phpLength of output: 237
UI Styling and Asset Verification Confirmed
The
lock_icon
is properly defined inincludes/Admin/Forms/Admin_Form_Builder.php
and is assigned the correct asset URI. The Tailwind CSS classes applied in the code snippet maintain a consistent UI styling, and there is no evidence of a broken image. No further changes are required.
44-44
:✅ Verification successful
Ensure compatibility with existing code that expects 'form-fields' panel.
The default panel has been changed from 'form-fields' to 'form-fields-v4-1'. Make sure all existing code that might depend on the 'form-fields' value has been updated to handle both values.
🏁 Script executed:
#!/bin/bash # Search for references to 'form-fields' that might need updates rg "form-fields['\"]" --type jsLength of output: 803
Code compatibility verified: Both 'form-fields' and 'form-fields-v4-1' are being handled correctly.
I searched for references and found that in files such as:
admin/form-builder/assets/js/form-builder.js
assets/js/wpuf-form-builder.js
assets/js/wpuf-form-builder-components.js
admin/form-builder/assets/js/components/form-fields/index.js
the code already checks for both
'form-fields'
and'form-fields-v4-1'
(e.g., using conditions likeif ('form-fields' === panel || 'form-fields-v4-1' === panel)
). This confirms that the compatibility concerns raised are adequately addressed.admin/form-builder/views/post-form-settings.php (2)
1-2
: Good use of Tailwind CSS for modern UI components.The container structure with Tailwind CSS classes provides a clean, modern interface for the form settings. The responsive design with flex layout ensures good usability.
284-602
: Well-structured field rendering function with good type support.The
wpuf_render_settings_field
function is well designed with support for multiple field types and proper handling of different field configurations. It appropriately handles default values, PRO features, and conditional rendering.src/css/admin/form-builder.css (25)
1-3
: Tailwind Directives: Proper Inclusion of Base, Components, and Utilities
The Tailwind directives are correctly included at the top of the file, establishing a clean foundation for the subsequent layers.
5-33
: Components Layer: Modular and Maintainable CSS
The use of the@layer components
block with Tailwind’s@apply
utility creates organized, component-scoped styles for buttons, tooltips, and other elements.
35-51
: Utilities Layer: Effective Use of Tailwind for Transitions and Transforms
Defining utilities such as transitions, durations, and transforms in a dedicated layer helps maintain consistency across the UI.
53-55
: Content Background Styling: Simple and Clear
The styling for#wpcontent
is straightforward and correctly sets a white background.
57-62
: Dropdown Transition Effects: Enhancing User Interaction
The transition styles for dropdown items are well defined using utility classes, ensuring smooth hover effects.
63-68
: Duplicate Background Property: Remove Redundantbackground-color
Within the.wpuf-pattern-1
rule,background-color: #ffffff;
is immediately overridden by the shorthandbackground
property. Removing the redundantbackground-color
will reduce confusion and adhere to best practices.- background-color: #ffffff;
🧰 Tools
🪛 Biome (1.9.4)
[error] 67-67: Unexpected shorthand property background after background-color
(lint/suspicious/noShorthandPropertyOverrides)
69-72
: Selectize Control Styling: Clear Custom Overrides
The custom styles for.selectize-control.multi
are clear. The use of!important
is acceptable for overriding default styles, but please verify that it does not cause conflicts elsewhere.
73-94
: Form Field Sizes: Responsive Width Adjustments
The selectors targeting various field sizes (small, medium, large) are well-structured and should deliver the intended responsive behavior.
95-104
: Icon Stroke Styling: Consistent Visual Feedback
The stroke adjustments for sidebar and module icons (default and hover states) are implemented correctly, ensuring a consistent visual experience.
105-115
: Selectize Control (Single) Styling: Clean and Functional
Styles for single selectize controls and dropdowns are concise and maintain a uniform appearance throughout the admin interface.
116-125
: Icon Container Setup: Optimal Layout
The.wpuf-icon-container
styling establishes a robust and responsive layout for icons, facilitating proper image display.
126-139
: Icon Image Styling: Ensuring Coverage and Transitions
Positioning and transition settings for images inside the icon container are correctly implemented, ensuring seamless fading effects and responsiveness.
140-158
: Shimmer Animation: Fluid Loading Effect
The keyframe-based shimmer animation is concise and effective at creating a smooth visual effect for loading indicators.
159-161
: Conditional Shimmer Display: Correct Use of Display None
The rule correctly hides the shimmer effect when the icon container has loaded its content.
171-179
: WebKit Slider Thumb: Good Practice
The styles targeting the WebKit slider thumb are appropriately specified and ensure a consistent look across supported browsers.
180-186
: Mozilla Slider Thumb: Consistent Styling
The styling for the Mozilla slider thumb mirrors that of the WebKit version, ensuring cross-browser compatibility.
187-196
: Range Input Hover States: Visual Feedback
The hover and active state styles for the range input (both for WebKit and Mozilla) are clear and provide proper user feedback during interaction.
197-199
: Table Cell Padding: Adequate Spacing
The padding for table cells in the option field chooser is minimal and should provide sufficient spacing.
200-212
: Selectize Control Icon: Font Awesome Integration
The pseudo-element for the selectize control leverages Font Awesome effectively. Please ensure the Font Awesome library is loaded and available in the project.
216-219
: Core UI Select Styling: Minimal Adjustments
Adjustments for select elements under.wp-core-ui
—specifically settingline-height
and removing padding—are minimal and appear intentional.
220-223
: Media Buttons Layout: Flex Alignment Works Well
The flexbox settings for#wpuf-form-builder .wp-media-buttons
ensure that media buttons are well-aligned, contributing to a neat interface layout.
224-226
: Media Buttons Icon: Adequate Spacing
The margin applied to media button icons is appropriate and maintains clear separation from adjacent elements.
227-238
: Button and Link Styling in Media Buttons: Consistency
The background, padding, border, and color definitions for buttons and links within the media buttons container are consistent and should yield a uniform look.
239-241
: Media Buttons Spacing: Correct Margin Setup
The additional right margin for the insert-media button is applied correctly, ensuring adequate spacing between elements.
242-246
: Hover States for Media Buttons: Visual Clarity
The hover state for both the insert-media button and link shifts the background and text colors appropriately, enhancing user feedback.admin/form-builder/assets/js/form-builder.js (28)
44-45
: Use updated panel
This sets the current panel to'form-fields-v4-1'
by default, ensuring consistency with the new interface. Looks good.
71-71
: Consistent reset ofediting_field_id
Resettingediting_field_id
when switching to'form-fields'
or'form-fields-v4-1'
is logical to avoid leftover state. Good job.
91-94
: Good approach to filter by field ID
UsingparseInt
for the comparison is correct. Implementation looks clean.
240-240
: Switchingcurrent_panel
on delete
Automatically revertingcurrent_panel
to'form-fields-v4-1'
upon field deletion keeps the UI consistent.
393-396
: New mutation:set_panel_sections
Straightforward logic to replace the panel sections in the store, improving maintainability.
399-401
: New mutation:set_default_panel_sections
Provides a handy way to revert to default panel sections when needed.
420-421
: New data props:isDirty
andshortcodeCopied
These help track unsaved changes and the copied shortcode state.
422-428
: Initializing additional settings data
logoUrl
,settings_titles
,settings_items
,active_tab
,form_settings
, andactive_settings_tab
align well with the builder’s requirements.
467-468
: String concatenation for meta fields
.join()
defaults to a comma separator, which appears correct for this usage.
487-497
: Watchers for reactive updates
Detecting changes onform_fields
andactive_settings_tab
ensures timely updates and re-initialization. Nicely done.
574-577
: MethodsetActiveSettingsTab
Assigning the active settings tab from the event’shref
is straightforward.
585-587
: Panel sections reset
Restoringpanel_sections
from defaults keeps the form builder consistent when returning to'form-fields-v4-1'
.
649-650
: Save form builder: concluding lines
No functional changes; appears to be code formatting or consolidation.
671-679
:switch_settings_menu
method
Smoothly shifts between menu items and updatesactive_settings_title
.
680-682
:switch_form_settings_pic_radio_item
Assigningform_settings[key] = value
is a concise way to sync radio options.
693-694
: Code block visibility
No new functionality added here, so no concerns.
933-935
: Instantiation ofFormDependencyHandler
Conditionally loading dependencies forwpuf_forms
is an efficient check.
939-941
: Showing the 'general' tab on load
Ensures a sensible default tab for new sessions.
943-950
:show_settings_for
function
Uses fadeIn/fadeOut to toggle settings panels. Straightforward and readable.
952-956
: Sidebar menu event handlers
Each list item click properly delegates to show the respective panel.
958-960
: Modules menu toggle
Switches to the 'modules' panel on click. Implementation is clear.
963-967
:FormDependencyHandler
constructor
Setup of the dependency configuration is well-structured for dynamic field visibility.
979-983
: Field listener attachments
Gathering unique control fields and binding change handlers is a good approach to handle dependencies.
985-987
: Initial dependency checks
Ensures the correct UI state is displayed upon page load.
1000-1005
: Handling radios and checkboxes
Good logic to handle individual radio inputs rather than a single group event.
1070-1073
: Toggling mobile menu
Straightforward toggling of classes for responsive behavior.
1075-1078
:post_type
change event
Invokespopulate_default_categories
as intended for dynamic configuration.
1079-1114
: Improve error handling in AJAX call
This still only logs errors to the console. Providing user-facing error messages or a fallback would enhance UX.
echo $icon; | ||
?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add proper escaping for icon output.
The icon variable is being output directly without any escaping, which could potentially lead to XSS vulnerabilities if the icon data contains malicious code.
<?php
-echo $icon;
+echo wp_kses_post($icon);
?>
The same issue occurs in other places where icons are echoed directly.
Also applies to: 42-43, 72-73
@click.prevent="" | ||
class="wpuf-inline-flex wpuf-items-center wpuf-gap-x-2 wpuf-rounded-md wpuf-px-8 wpuf-py-3 wpuf-text-gray-700 hover:wpuf-text-gray-700 hover:wpuf-bg-gray-50 wpuf-ring-1 wpuf-ring-inset wpuf-ring-gray-300"><?php esc_html_e( 'Cancel', 'wp-user-frontend' ); ?> | ||
</button> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Implement functionality for the Cancel button.
The Cancel button has an empty @click.prevent=""
handler, which prevents the default action but doesn't provide any functionality. Consider adding a handler to navigate away from the form or reset changes.
<button
- @click.prevent=""
+ @click.prevent="cancel_form_editing"
class="wpuf-inline-flex wpuf-items-center wpuf-gap-x-2 wpuf-rounded-md wpuf-px-8 wpuf-py-3 wpuf-text-gray-700 hover:wpuf-text-gray-700 hover:wpuf-bg-gray-50 wpuf-ring-1 wpuf-ring-inset wpuf-ring-gray-300"><?php esc_html_e( 'Cancel', 'wp-user-frontend' ); ?>
</button>
📝 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.
@click.prevent="" | |
class="wpuf-inline-flex wpuf-items-center wpuf-gap-x-2 wpuf-rounded-md wpuf-px-8 wpuf-py-3 wpuf-text-gray-700 hover:wpuf-text-gray-700 hover:wpuf-bg-gray-50 wpuf-ring-1 wpuf-ring-inset wpuf-ring-gray-300"><?php esc_html_e( 'Cancel', 'wp-user-frontend' ); ?> | |
</button> | |
@click.prevent="cancel_form_editing" | |
class="wpuf-inline-flex wpuf-items-center wpuf-gap-x-2 wpuf-rounded-md wpuf-px-8 wpuf-py-3 wpuf-text-gray-700 hover:wpuf-text-gray-700 hover:wpuf-bg-gray-50 wpuf-ring-1 wpuf-ring-inset wpuf-ring-gray-300"><?php esc_html_e( 'Cancel', 'wp-user-frontend' ); ?> | |
</button> |
id="<?php echo $inner_field_key; ?>" | ||
name="<?php echo $inner_field_key; ?>" | ||
data-value="<?php echo $value_str; ?>" | ||
:class="setting_class_names('dropdown')"> | ||
<?php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix name attribute in nested select fields.
The name
attribute for select fields in the inline_fields section doesn't follow the same pattern as other form fields. It should include the wpuf_settings
array prefix to ensure proper form submission.
<select
id="<?php echo $inner_field_key; ?>"
- name="<?php echo $inner_field_key; ?>"
+ name="wpuf_settings[<?php echo $inner_field_key; ?>]"
data-value="<?php echo $value_str; ?>"
:class="setting_class_names('dropdown')">
📝 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.
id="<?php echo $inner_field_key; ?>" | |
name="<?php echo $inner_field_key; ?>" | |
data-value="<?php echo $value_str; ?>" | |
:class="setting_class_names('dropdown')"> | |
<?php | |
<select | |
id="<?php echo $inner_field_key; ?>" | |
name="wpuf_settings[<?php echo $inner_field_key; ?>]" | |
data-value="<?php echo $value_str; ?>" | |
:class="setting_class_names('dropdown')"> | |
<?php |
for="<?php echo $field_key; ?>" | ||
class="wpuf-mr-2 wpuf-text-sm wpuf-text-gray-700"> | ||
<?php echo $option['label']; ?> | ||
</div> | ||
<?php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix unclosed label tag in pic-radio field type.
The label tag that wraps the field label text is not properly closed before the closing div tag. This could cause layout issues or invalid HTML.
<label
for="<?php echo $field_key; ?>"
class="wpuf-mr-2 wpuf-text-sm wpuf-text-gray-700">
<?php echo $option['label']; ?>
+</label>
</div>
📝 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.
for="<?php echo $field_key; ?>" | |
class="wpuf-mr-2 wpuf-text-sm wpuf-text-gray-700"> | |
<?php echo $option['label']; ?> | |
</div> | |
<?php | |
<label | |
for="<?php echo $field_key; ?>" | |
class="wpuf-mr-2 wpuf-text-sm wpuf-text-gray-700"> | |
<?php echo $option['label']; ?> | |
</label> | |
</div> | |
<?php |
:class="<?php echo $field['trailing_type'] === 'number'; ?> ? 'wpuf-p-1' : 'wpuf-p-2'" | ||
class="wpuf-absolute wpuf-top-0 wpuf--right-px wpuf-h-full wpuf-bg-gray-50 wpuf-rounded-r-sm wpuf-text-gray-700 wpuf-border wpuf-border-gray-300 wpuf-p-1"> | ||
<?php echo $field['trailing_text']; ?> | ||
</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Vue/PHP expression in class binding.
The current implementation mixes PHP and Vue.js syntax in a way that could cause issues. The PHP expression <?php echo $field['trailing_type'] === 'number'; ?>
evaluates to a boolean which isn't compatible with Vue's class binding.
<span
- :class="<?php echo $field['trailing_type'] === 'number'; ?> ? 'wpuf-p-1' : 'wpuf-p-2'"
+ :class="'<?php echo $field['trailing_type']; ?>' === 'number' ? 'wpuf-p-1' : 'wpuf-p-2'"
class="wpuf-absolute wpuf-top-0 wpuf--right-px wpuf-h-full wpuf-bg-gray-50 wpuf-rounded-r-sm wpuf-text-gray-700 wpuf-border wpuf-border-gray-300 wpuf-p-1">
<?php echo $field['trailing_text']; ?>
</span>
📝 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.
:class="<?php echo $field['trailing_type'] === 'number'; ?> ? 'wpuf-p-1' : 'wpuf-p-2'" | |
class="wpuf-absolute wpuf-top-0 wpuf--right-px wpuf-h-full wpuf-bg-gray-50 wpuf-rounded-r-sm wpuf-text-gray-700 wpuf-border wpuf-border-gray-300 wpuf-p-1"> | |
<?php echo $field['trailing_text']; ?> | |
</span> | |
<span | |
:class="'<?php echo $field['trailing_type']; ?>' === 'number' ? 'wpuf-p-1' : 'wpuf-p-2'" | |
class="wpuf-absolute wpuf-top-0 wpuf--right-px wpuf-h-full wpuf-bg-gray-50 wpuf-rounded-r-sm wpuf-text-gray-700 wpuf-border wpuf-border-gray-300 wpuf-p-1"> | |
<?php echo $field['trailing_text']; ?> | |
</span> |
box-shadow: none; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File Termination: Ensure Proper Closure
Static analysis indicates that the file is missing a closing curly brace at the end. Please confirm that all rule blocks are properly closed to prevent potential CSS parsing issues.
🧰 Tools
🪛 Biome (1.9.4)
[error] 258-258: expected }
but instead the file ends
the file ends here
(parse)
#wpuf-form-builder .wp-editor-tabs { | ||
position: absolute; | ||
bottom: 0; | ||
right: 0; | ||
} | ||
#wpuf-form-builder .wp-editor-tabs button { | ||
padding: 10px 16px 30px; | ||
border-radius: 6px 6px 0 0; | ||
} | ||
#wpuf-form-builder .wp-editor-tabs .wp-switch-editor:focus { | ||
box-shadow: none; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing Closing Bracket: Incomplete Rule Block
The CSS rule for #wpuf-form-builder .wp-editor-tabs .wp-switch-editor:focus
is missing its closing curly brace, which can lead to parsing errors and unintended style leaks.
@@ at end of file @@
-#wpuf-form-builder .wp-editor-tabs .wp-switch-editor:focus {
- box-shadow: none;
-// Missing closing brace
+#wpuf-form-builder .wp-editor-tabs .wp-switch-editor:focus {
+ box-shadow: none;
+}
Committable suggestion skipped: line range outside the PR's diff.
fixes #676, fixes #668, fixes #669, fixes #670, fixes #671
post form builder settings revamp
Summary by CodeRabbit
New Features
Style
Refactor