Skip to content

Conversation

@enejb
Copy link
Member

@enejb enejb commented Jan 15, 2026

Proposed changes:

  • Add granular block categories (Input, Contact, Choice, Other) specifically for the Jetpack Form editor
  • Each form field block now defines its formEditorCategory property to specify which category it belongs to in the form editor
  • Categories are dynamically registered when entering the form editor and removed when leaving
  • Block category overrides are applied only in the form editor context, keeping the original contact-form category for the regular post/page editor
  • Add missing field blocks to the allowed blocks list: field-hidden, field-time, field-slider, field-image-select
  • Fix incorrect block name field-file-uploadfield-file
  • Add missing supporting blocks: dropzone, input-range, input-rating, fieldset-image-options, input-image-option

Before:

Screenshot 2026-01-15 at 12 06 14 PM

After:
Screenshot 2026-01-19 at 9 22 57 AM

Block categorization:

Category Blocks
Basic number, field-text, field-textarea, field-date, field-time,
Contact field-name, field-email, field-telephone, field-url
Choice field-checkbox, field-select, field-radio, field-checkbox-multiple, field-image-select
Advanced field-consent, field-hidden, field-file, field-rating, field-slider

Other information:

  • Have you written new tests for your changes, if applicable?
  • Have you checked the E2E test CI results, and verified that your changes do not break them?
  • Have you tested your changes on WordPress.com, if applicable (if so, you'll see a generated comment below with a script to run)?

Jetpack product discussion

no

Does this pull request change what data or activity we track or use?

no

Testing instructions:

  1. Enable the central-form-management feature flag if not already enabled
add_filter( 'jetpack_block_editor_feature_flags', 'eb_register_feature' );

function eb_register_feature( $flags ) {
   $flags['central-form-management'] = true;
   return $flags;
}
  1. Go to Forms > Add New to create a new form (or navigate to /wp-admin/post-new.php?post_type=jetpack_form)
  2. Open the block inserter (click the + button or press /)
  3. Verify that form field blocks are organized into four categories:
    • Input: Text input field, Multi-line text field, Number input field, Hidden field
    • Contact: Name field, Email field, Phone number field, Website field
    • Choice: Checkbox, Dropdown, Single choice, Multiple choice, Terms consent, Rating, Image Select
    • Other: Date picker, Time input, File upload, Slider
  4. Add blocks from each category to verify they work correctly
  5. Navigate to a regular post or page editor
  6. Add a Form block and verify the form fields are all grouped under the single "Forms" category (not the granular categories)
  7. Return to the form editor and verify the granular categories are still displayed

Visit the form editor by going to

Copilot AI review requested due to automatic review settings January 15, 2026 19:50
@github-actions
Copy link
Contributor

github-actions bot commented Jan 15, 2026

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack), and enable the update/jetpack-form-editor-add-categories branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack update/jetpack-form-editor-add-categories

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@github-actions
Copy link
Contributor

github-actions bot commented Jan 15, 2026

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

@github-actions github-actions bot added the [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. label Jan 15, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds granular block categories to the Jetpack Form editor to improve organization of form field blocks in the block inserter. Instead of a single "Forms" category, form fields are now organized into four categories: Input, Contact, Choice, and Other.

Changes:

  • Added dynamic block category registration/unregistration for the form editor context
  • Implemented block category override system using WordPress hooks to remap blocks to granular categories
  • Updated all form field blocks with formEditorCategory property
  • Fixed missing and incorrect block names in allowed blocks list

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
projects/packages/forms/src/form-editor/utils/form-categories.ts New file defining the four granular categories and mapping logic
projects/packages/forms/src/form-editor/utils/block-category-override.ts New file implementing dynamic block category override system
projects/packages/forms/src/form-editor/utils/category-utils.ts Added functions to register/unregister form categories
projects/packages/forms/src/form-editor/index.tsx Integrated category setup/restoration logic into form editor lifecycle
projects/packages/forms/src/form-editor/class-form-editor.php Fixed incorrect block name and added missing field/supporting blocks to allowed list
projects/packages/forms/src/blocks/field-*.js Added formEditorCategory property to each form field block definition
projects/packages/forms/changelog/update-jetpack-form-editor-add-categories Changelog entry for the feature
Comments suppressed due to low confidence (2)

projects/packages/forms/src/form-editor/utils/form-categories.ts:1

  • The JSDoc example in the @param and @return descriptions is inconsistent with the actual implementation. The example uses 'text' as input and 'form-text' as output, but according to the CATEGORY_SLUG_MAP, 'text' is not a valid key. The example should use 'input' → 'form-input' instead to match the actual mapping.
/**

projects/packages/forms/changelog/update-jetpack-form-editor-add-categories:4

  • The changelog entry should not include the package name prefix "Form Editor" at the end since this is within the forms package changelog. Additionally, the entry should be shorter and use imperative mood. Consider: "Add granular block categories (Input, Contact, Choice, Other) to improve form field organization in the block inserter."
Added granular block categories (Input, Contact, Choice, Other) for better organization of form fields in the block inserter on the Form Editor.

@jp-launch-control
Copy link

jp-launch-control bot commented Jan 15, 2026

Code Coverage Summary

Cannot generate coverage summary while tests are failing. 🤐

Please fix the tests, or re-run the Code coverage job if it was something being flaky.

Full summary · PHP report · JS report

@enejb enejb added [Status] Needs Review This PR is ready for review. and removed [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. labels Jan 15, 2026
Copilot AI review requested due to automatic review settings January 15, 2026 22:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 4 comments.

originalBlockCategories.set( blockType.name, blockType.category );
}
// Update the block type's category
blockType.category = formCategorySlug;
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

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

Directly mutating the blockType.category property could cause issues since you're modifying objects returned from the data store. While this may work, it's generally better practice to use the appropriate dispatch methods if available. Consider checking if there's a proper API for updating block type properties, or document why direct mutation is necessary here.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings January 15, 2026 22:20
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 2 comments.

* 2. Activates block category overrides to move blocks to the new categories
* 3. Moves the contact-form category to the front (as a fallback for non-field blocks)
*
* @return {unknown[]} previous categories array for restoration
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

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

The return type annotation uses JSDoc-style comment in a TypeScript file. Consider using TypeScript's type annotation directly in the function signature instead, or at minimum update the JSDoc syntax to match TypeScript conventions (e.g., '@returns' instead of '@return').

Copilot uses AI. Check for mistakes.
@ilonagl
Copy link

ilonagl commented Jan 16, 2026

Yay, very nice!! Thanks for doing this, @enejb!

@simison
Copy link
Member

simison commented Jan 16, 2026

Nice! This is really starting to take a form builder shape.

Here's a set of suggestions for categories and which fields to have in them. All open to feedback of course.

Category Fields
Basic Text, Textarea, Number, Date, Time
Contact info Name, First name, Last name, Email, Phone number, Website
Choice Checkbox, Dropdown, Single choice, Multiple choice, Image select
Advanced File upload, Slider, Stars rating, Hearts rating, Hidden, Terms Consent

Reasoning:

  • Input → "Basic", "Standard", or "Common" could be a more descriptive fit here? — everything is "input" or "field".
  • Contact → rename to Contact info: feels like this would translate better in different languages without ambiguity. "Contact" also works, but we need to make sure nobody translates it as a noun or verb.
  • Hidden field → Move to Other category: it's a fairly esoteric field, so having it at the top in the "common" category felt off.
  • Date/time → Feels basic/common enough to justify top placement rather than "other" bucket way down.
  • Terms Concent → while it's a "choice" it's more specialized than that, so advanced made sense to me.
  • Stars/Hearts rating → same as above; this one is more similar to slider or number semantically than to radios/checkboxes.

@ilonagl
Copy link

ilonagl commented Jan 16, 2026

As a rule of thumb, I’ve been following Typeform’s grouping, as users are likely familiar with it and Typeform has done extensive research to validate it.

Screenshot 2026-01-16 at 14 44 03

and my initial recommendation:

From_block_inserter

@simison I agree with your proposal, here are some notes:

Hidden field → Move to Other category: it's a fairly esoteric field, so having it at the top in the "common" category felt off.

Agreed, had a similar thought.

Contact → rename to Contact info

+1.

Input → "Basic", "Standard", or "Common"

Maybe even "Recommended" or "Most common" would work here?

Basic: Text, Textarea, Number, Date, Time

The time is not fully there UX-wise (we don't have a great ability to select and only input time), so I wonder if it should be this high up?

Separate note:

Name, First name, Last name

The fact that we have three different inputs for very similar purposes seems a bit off for me. Are they supposed to be variations or separate inputs?

@simison
Copy link
Member

simison commented Jan 16, 2026

Maybe even "Recommended" or "Most common" would work here?

Yep 👍 Common can be hard to translate since it has multiple meanings, so we'll need to be mindful what context to provide to translators so they get it right. Leaning towards "common" over "recommended" for a more neutral feeling.

The fact that we have three different inputs for very similar purposes seems a bit off for me. Are they supposed to be variations or separate inputs?

Yep, they're all variations of Name field but Gutenberg surfaces them all separately in the block picker. Same with Hearts/Stars rating. Helps with search, but adds a bit of noise in a list like this. Not a biggie, methinks. Semantically, they carry a clearly separate meaning for integrations and for form autofilling, so they're important to have.

The time is not fully there UX-wise (we don't have a great ability to select and only input time), so I wonder if it should be this high up?

I agree UX can/should be improved, but feels odd to have time & date far apart in different locations? At the end, it's just simple numbers that users can just enter, so selection doesn't feel that critical for UX. Time doesn't seem as common need as date for sure, but just seems sensible to keep them close together. I'm fine keeping them both in other/advanced category as well.

const name = 'field-checkbox';
const settings = {
...defaultSettings,
formEditorCategory: 'choice',
Copy link
Member

Choose a reason for hiding this comment

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

I'm a bit concerned about including this in settings since it isn't part of block schema. Is there another way to provide remapping?

I like that it's in the same file as the block so could be something we just export as constant from here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried implementing this in a different way but we always end up under a different place.

I think support make more sense and this will become even more extensible if we implement other feature this way. Since we already prefix them with the custom post type.

Copy link
Member

@simison simison Jan 20, 2026

Choose a reason for hiding this comment

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

What I'm worried that settings has a very specific schema in Gutenberg, and adding custom elements can break or start throwing warnings in future in surprising ways.

It's already better; it's now prefixed with jetpack_, so there's no chance of confusion.

Did you look if export default { name, settings, jetpackCptCategory }; would work?

Comment on lines 46 to 49
input: 'form-input',
contact: 'form-contact',
choice: 'form-choice',
other: 'form-other',
Copy link
Member

Choose a reason for hiding this comment

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

Should we prefix with jetpack just case like we do with our other categories elsewhere?

Copy link
Member Author

@enejb enejb Jan 19, 2026

Choose a reason for hiding this comment

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

I don't think we need to. Since we currently don't prefix any category names like this. As far as I can tell.

Copilot AI review requested due to automatic review settings January 19, 2026 17:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings January 19, 2026 21:53
Copy link
Contributor

@edanzer edanzer left a comment

Choose a reason for hiding this comment

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

This tests largely as expected. Note: categories in the code are different than the PR description. The ones in the code are the right ones (see list below).

  • Create new form post, open block inserter, and confirm blocks are in new categories
  • Basic category contains: Text, Number, Multiline, Date, Time
  • Contact category contains: Name, First Name, Last Name, Email, Phone, Website
  • Choice category contains: Checkbox, Dropdown, Single choice, Multiple choice, Image Select
  • Other category contains: Consent, Hidden, Ratings, File, Slider
  • Add blocks to verify they work correctly
  • Go to normal page/post, insert form block, and confirm fields are all under usual Forms category.
  • Return to the form editor and verify the granular categories are still displayed

I added a few questions.

General feedback. My single biggest question/concern though is this: It's not clear to me that dividing the form fields into these categories makes it any easier to find specific fields I want. Without this PR, we do not have that many fields, and it's easy to scan a single Form category. With this PR, the way fields are divided into categories seems a bit arbitrary. It's not obvious what category I should look for to find a specific field. And I wonder if people will just have to kind of scan all the categories to find a field, rather than a single more condense Form category. cc @ilonagl @simison too.

I should add - I don't think it's a huge concern either way. So I'm ok rolling with this too. But I do wonder if we add a lot of complexity for not that much user benefit.

edanzer
edanzer previously approved these changes Jan 20, 2026
enejb and others added 13 commits January 20, 2026 11:35
Introduces granular categories (input, contact, choice, other) for form field blocks in the Jetpack Form editor. Adds a `formEditorCategory` property to each field block and utilities to register/unregister these categories and override block categories dynamically. Updates the form editor logic to use these new categories, improving block organization and user experience.
Introduces unit tests for registerFormCategories and unregisterFormCategories to verify correct category insertion, removal, immutability, and reversibility.
Co-authored-by: Copilot <[email protected]>
Simplifies the logic for overriding block categories in the form editor by using a filter and the reapplyBlockTypeFilters dispatch action. Removes manual tracking and restoration of original categories, and introduces an activation flag to control when overrides are applied. This improves maintainability and ensures categories are updated consistently.
 Category assignments:
  - Basic: Text, Textarea, Number, Date, Time
  - Contact info: Name, Email, Phone number, Website
  - Choice: Checkbox, Dropdown, Single choice, Multiple choice, Image select
  - Advanced: File upload, Slider, Rating, Hidden, Terms Consent
@enejb enejb force-pushed the update/jetpack-form-editor-add-categories branch from 4c2695f to d5401e3 Compare January 20, 2026 19:43
Copilot AI review requested due to automatic review settings January 20, 2026 20:10
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 32 out of 32 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

projects/packages/forms/tests/php/form-editor/Form_Editor_Test.php:424

  • The test's expected supporting blocks list is missing the newly added supporting blocks: 'jetpack/dropzone', 'jetpack/input-range', 'jetpack/input-rating', 'jetpack/fieldset-image-options', and 'jetpack/input-image-option'. These blocks were added to the allowed list in the PHP code but are not verified by this test. Add these blocks to the expected_supporting_blocks array to ensure the test validates the complete allowed blocks list.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI review requested due to automatic review settings January 21, 2026 12:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 32 out of 32 changed files in this pull request and generated 22 comments.

Comments suppressed due to low confidence (1)

projects/packages/forms/tests/php/form-editor/Form_Editor_Test.php:465

  • The test_allowed_blocks_list_completeness test is missing the newly added field blocks (field-hidden, field-time, field-slider, field-image-select) and supporting blocks (dropzone, input-range, input-rating, fieldset-image-options, input-image-option). These should be added to the expected blocks arrays to ensure comprehensive test coverage of the allowed blocks list.

Comment on lines +21 to +23
supports: {
...defaultSettings.supports,
},
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The supports object is redundantly spreading defaultSettings.supports without adding any new properties. Since no additional support properties are being added, this spread operation is unnecessary. Consider removing this redundant code or only include it if additional properties need to be added.

Suggested change
supports: {
...defaultSettings.supports,
},

Copilot uses AI. Check for mistakes.
export const name = 'field-date';

export const form_editor = {
category: 'advanced',
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The field-date block is categorized as 'advanced' but according to the PR description, it should be in the 'Basic' category. The PR description table states: "Basic: number, field-text, field-textarea, field-date, field-time". Please update the category to 'basic' to match the intended design.

Suggested change
category: 'advanced',
category: 'basic',

Copilot uses AI. Check for mistakes.
export const name = 'field-time';

export const form_editor = {
category: 'advanced',
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The field-time block is categorized as 'advanced' but according to the PR description, it should be in the 'Basic' category. The PR description table states: "Basic: number, field-text, field-textarea, field-date, field-time". Please update the category to 'basic' to match the intended design.

Suggested change
category: 'advanced',
category: 'basic',

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +19
supports: {
...defaultSettings.supports,
},
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The supports object is redundantly spreading defaultSettings.supports without adding any new properties. Since no additional support properties are being added, this spread operation is unnecessary. Consider removing this redundant code or only include it if additional properties need to be added.

Suggested change
supports: {
...defaultSettings.supports,
},

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +19
supports: {
...defaultSettings.supports,
},
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The supports object is redundantly spreading defaultSettings.supports without adding any new properties. Since no additional support properties are being added, this spread operation is unnecessary. Consider removing this redundant code or only include it if additional properties need to be added.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +19
supports: {
...defaultSettings.supports,
},
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The supports object is redundantly spreading defaultSettings.supports without adding any new properties. Since no additional support properties are being added, this spread operation is unnecessary. Consider removing this redundant code or only include it if additional properties need to be added.

Suggested change
supports: {
...defaultSettings.supports,
},

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +19
supports: {
...defaultSettings.supports,
},
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The supports object is redundantly spreading defaultSettings.supports without adding any new properties. Since no additional support properties are being added, this spread operation is unnecessary. Consider removing this redundant code or only include it if additional properties need to be added.

Suggested change
supports: {
...defaultSettings.supports,
},

Copilot uses AI. Check for mistakes.
Significance: minor
Type: added

Added granular block categories for better organization of form fields in the block inserter on the Form Editor.
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The changelog entry should use imperative mood. Change "Added" to "Add" to follow the project's changelog guidelines.

Copilot generated this review using guidance from repository custom instructions.
/**
* Filter callback that overrides block categories for form field blocks.
*
* This reads the category from supports.jetpack_form.category and maps
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The JSDoc comment incorrectly states "reads the category from supports.jetpack_form.category" but the implementation actually reads from form_editor.category on the childBlock object. Update the documentation to accurately reflect the implementation.

Suggested change
* This reads the category from supports.jetpack_form.category and maps
* This reads the category from each child block's `form_editor.category` field and maps

Copilot uses AI. Check for mistakes.
/**
* Map of short category names to full category slugs.
*
* Blocks define their category in supports.jetpack_form.category using the short name
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The JSDoc comment incorrectly states "Blocks define their category in supports.jetpack_form.category" but blocks actually define it in the form_editor.category property. Update the documentation to accurately reflect the implementation.

Suggested change
* Blocks define their category in supports.jetpack_form.category using the short name
* Blocks define their category in form_editor.category using the short name

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants