-
Notifications
You must be signed in to change notification settings - Fork 849
Forms: Add granular block categories to form editor #46626
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
base: trunk
Are you sure you want to change the base?
Conversation
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
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:
If you have questions about anything, reach out in #jetpack-developers for guidance! |
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.
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
formEditorCategoryproperty - 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
@paramand@returndescriptions 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.
projects/packages/forms/src/form-editor/utils/category-utils.ts
Outdated
Show resolved
Hide resolved
projects/packages/forms/src/form-editor/utils/block-category-override.ts
Show resolved
Hide resolved
Code Coverage SummaryCannot generate coverage summary while tests are failing. 🤐 Please fix the tests, or re-run the Code coverage job if it was something being flaky. |
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.
Pull request overview
Copilot reviewed 25 out of 25 changed files in this pull request and generated 4 comments.
projects/packages/forms/src/form-editor/utils/form-categories.ts
Outdated
Show resolved
Hide resolved
| originalBlockCategories.set( blockType.name, blockType.category ); | ||
| } | ||
| // Update the block type's category | ||
| blockType.category = formCategorySlug; |
Copilot
AI
Jan 15, 2026
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.
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.
projects/packages/forms/src/form-editor/utils/block-category-override.ts
Outdated
Show resolved
Hide resolved
projects/packages/forms/changelog/update-jetpack-form-editor-add-categories
Outdated
Show resolved
Hide resolved
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.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated 2 comments.
projects/packages/forms/src/form-editor/utils/test/category-utils.test.ts
Outdated
Show resolved
Hide resolved
| * 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 |
Copilot
AI
Jan 15, 2026
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.
|
Yay, very nice!! Thanks for doing this, @enejb! |
|
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.
Reasoning:
|
|
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.
and my initial recommendation:
@simison I agree with your proposal, here are some notes:
Agreed, had a similar thought.
+1.
Maybe even "Recommended" or "Most common" would work here?
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:
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 👍 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.
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.
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', |
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.
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?
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.
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.
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.
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?
| input: 'form-input', | ||
| contact: 'form-contact', | ||
| choice: 'form-choice', | ||
| other: 'form-other', |
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.
Should we prefix with jetpack just case like we do with our other categories elsewhere?
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.
I don't think we need to. Since we currently don't prefix any category names like this. As far as I can tell.
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.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.
projects/packages/forms/changelog/update-jetpack-form-editor-add-categories
Outdated
Show resolved
Hide resolved
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.
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.
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
4c2695f to
d5401e3
Compare
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.
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.
projects/packages/forms/changelog/update-jetpack-form-editor-add-categories
Outdated
Show resolved
Hide resolved
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.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
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.
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.
| supports: { | ||
| ...defaultSettings.supports, | ||
| }, |
Copilot
AI
Jan 21, 2026
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.
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.
| supports: { | |
| ...defaultSettings.supports, | |
| }, |
| export const name = 'field-date'; | ||
|
|
||
| export const form_editor = { | ||
| category: 'advanced', |
Copilot
AI
Jan 21, 2026
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.
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.
| category: 'advanced', | |
| category: 'basic', |
| export const name = 'field-time'; | ||
|
|
||
| export const form_editor = { | ||
| category: 'advanced', |
Copilot
AI
Jan 21, 2026
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.
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.
| category: 'advanced', | |
| category: 'basic', |
| supports: { | ||
| ...defaultSettings.supports, | ||
| }, |
Copilot
AI
Jan 21, 2026
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.
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.
| supports: { | |
| ...defaultSettings.supports, | |
| }, |
| supports: { | ||
| ...defaultSettings.supports, | ||
| }, |
Copilot
AI
Jan 21, 2026
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.
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.
| supports: { | ||
| ...defaultSettings.supports, | ||
| }, |
Copilot
AI
Jan 21, 2026
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.
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.
| supports: { | |
| ...defaultSettings.supports, | |
| }, |
| supports: { | ||
| ...defaultSettings.supports, | ||
| }, |
Copilot
AI
Jan 21, 2026
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.
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.
| supports: { | |
| ...defaultSettings.supports, | |
| }, |
| Significance: minor | ||
| Type: added | ||
|
|
||
| Added granular block categories for better organization of form fields in the block inserter on the Form Editor. |
Copilot
AI
Jan 21, 2026
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.
The changelog entry should use imperative mood. Change "Added" to "Add" to follow the project's changelog guidelines.
| /** | ||
| * Filter callback that overrides block categories for form field blocks. | ||
| * | ||
| * This reads the category from supports.jetpack_form.category and maps |
Copilot
AI
Jan 21, 2026
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.
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.
| * 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 |
| /** | ||
| * Map of short category names to full category slugs. | ||
| * | ||
| * Blocks define their category in supports.jetpack_form.category using the short name |
Copilot
AI
Jan 21, 2026
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.
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.
| * 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 |


Proposed changes:
formEditorCategoryproperty to specify which category it belongs to in the form editorcontact-formcategory for the regular post/page editorfield-hidden,field-time,field-slider,field-image-selectfield-file-upload→field-filedropzone,input-range,input-rating,fieldset-image-options,input-image-optionBefore:
After:

Block categorization:
Other information:
Jetpack product discussion
no
Does this pull request change what data or activity we track or use?
no
Testing instructions:
central-form-managementfeature flag if not already enabled/wp-admin/post-new.php?post_type=jetpack_form)+button or press/)Visit the form editor by going to