From 5d61ca2deb0663fb63adfe5b7ca9e8186230f43b Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Thu, 25 Jun 2026 11:19:34 -0300 Subject: [PATCH 01/14] Forms: disable block visibility control on fields and inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Device/viewport visibility ("Hide on…") is not honored on the field wrapper at render time — the field render pipeline bypasses core's render_block visibility filter — so the control did nothing. Disable the 'visibility' block support on field and input blocks on both the JS (shared/settings, input) and PHP (register_block_type_args filter) registrations so the non-functional option no longer appears. Labels keep visibility support. See FORMS-694. Co-Authored-By: Claude Opus 4.8 --- ...fix-forms-disable-field-visibility-control | 4 +++ .../contact-form/class-contact-form-block.php | 34 +++++++++++++++++++ .../packages/forms/src/blocks/input/index.js | 3 ++ .../forms/src/blocks/shared/settings/index.js | 5 +++ 4 files changed, 46 insertions(+) create mode 100644 projects/packages/forms/changelog/fix-forms-disable-field-visibility-control diff --git a/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control b/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control new file mode 100644 index 000000000000..b13642fa0cb9 --- /dev/null +++ b/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Forms: Disable the block visibility ("Hide on…") control on form fields and inputs, where it had no effect on the frontend. Labels keep their visibility support. diff --git a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php index a7bd4c23050d..bddcf584a3db 100644 --- a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php +++ b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php @@ -90,6 +90,35 @@ public static function register_block() { // Load AI integration after Jetpack_Gutenberg registers extensions (priority 10) add_action( 'enqueue_block_editor_assets', array( __CLASS__, 'maybe_load_ai_integration' ), 11 ); } + + /** + * Disable the block "visibility" support on form field and input blocks. + * + * Device/viewport visibility ("Hide on…") is not honored on the field + * wrapper at render time — the field render pipeline bypasses core's + * render_block visibility filter — so the control would do nothing. We + * disable the support so it does not appear. This mirrors the JS + * registration (shared/settings/index.js and input/index.js). Labels keep + * visibility support (handled separately via labelhiddenbyblockvisibility), + * and the internal field-option-* blocks are left untouched to match JS. + * + * @param array $args Block type registration args. + * @param string $block_name Block name being registered. + * @return array + */ + public static function disable_field_visibility_support( $args, $block_name ) { + $is_field = strpos( $block_name, 'jetpack/field-' ) === 0 && strpos( $block_name, 'jetpack/field-option-' ) !== 0; + + if ( 'jetpack/input' === $block_name || $is_field ) { + if ( ! isset( $args['supports'] ) || ! is_array( $args['supports'] ) ) { + $args['supports'] = array(); + } + $args['supports']['visibility'] = false; + } + + return $args; + } + /** * Register the contact form block feature flag. * @@ -171,6 +200,11 @@ public static function register_child_blocks() { return; } + // Keep the PHP-registered "visibility" support in sync with the JS + // registration (src/blocks/shared/settings/index.js and + // src/blocks/input/index.js), which disables it on fields and inputs. + add_filter( 'register_block_type_args', array( __CLASS__, 'disable_field_visibility_support' ), 10, 2 ); + // Field inner block types. Blocks::jetpack_register_block( 'jetpack/input', diff --git a/projects/packages/forms/src/blocks/input/index.js b/projects/packages/forms/src/blocks/input/index.js index 6cb54180811e..1e645098fa7a 100644 --- a/projects/packages/forms/src/blocks/input/index.js +++ b/projects/packages/forms/src/blocks/input/index.js @@ -32,6 +32,9 @@ const settings = { supports: { reusable: false, html: false, + // See FORMS-694: device/viewport visibility isn't honored on the field + // wrapper at render, so disable the control on the input too. + visibility: false, color: { text: true, background: true, diff --git a/projects/packages/forms/src/blocks/shared/settings/index.js b/projects/packages/forms/src/blocks/shared/settings/index.js index 3b103f123d1f..e23b9f5a50e8 100644 --- a/projects/packages/forms/src/blocks/shared/settings/index.js +++ b/projects/packages/forms/src/blocks/shared/settings/index.js @@ -30,6 +30,11 @@ export default { supports: { reusable: false, html: false, + // Device/viewport visibility ("Hide on…") is not honored on the field + // wrapper at render time, so disable the control on fields to avoid an + // option that does nothing. Labels keep visibility support (handled + // separately via labelhiddenbyblockvisibility). See FORMS-694. + visibility: false, __experimentalExposeControlsToChildren: true, }, transforms, From 0c21998729d7cf8c29e7b1b3a291ab3d755f5ffe Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Fri, 26 Jun 2026 10:05:06 -0300 Subject: [PATCH 02/14] Forms: update child-block supports test fixture for removed visibility control --- .../forms/tests/php/contact-form/Contact_Form_Block_Test.php | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/packages/forms/tests/php/contact-form/Contact_Form_Block_Test.php b/projects/packages/forms/tests/php/contact-form/Contact_Form_Block_Test.php index 5f6d00add923..e311e89cfde5 100644 --- a/projects/packages/forms/tests/php/contact-form/Contact_Form_Block_Test.php +++ b/projects/packages/forms/tests/php/contact-form/Contact_Form_Block_Test.php @@ -87,6 +87,7 @@ public static function data_provider_test_register_child_blocks() { '__experimentalTextDecoration' => true, '__experimentalLetterSpacing' => true, ), + 'visibility' => false, ), ), 'jetpack/label' => array( From 91d659737e37c9113edbdb16b7bbcf7c07f31848 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Fri, 26 Jun 2026 10:15:33 -0300 Subject: [PATCH 03/14] Forms: add TODO to refactor visibility-disable filter into shared supports array --- .../forms/src/blocks/contact-form/class-contact-form-block.php | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php index bddcf584a3db..0fb7e834e73d 100644 --- a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php +++ b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php @@ -107,6 +107,7 @@ public static function register_block() { * @return array */ public static function disable_field_visibility_support( $args, $block_name ) { + // TODO: refactor into an array_merge'd shared supports array mirroring the JS defaultSettings, instead of this filter. $is_field = strpos( $block_name, 'jetpack/field-' ) === 0 && strpos( $block_name, 'jetpack/field-option-' ) !== 0; if ( 'jetpack/input' === $block_name || $is_field ) { From 9fb35579a2f0ef4d90a2a2e93f501985429ec3d2 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Mon, 29 Jun 2026 00:26:58 -0300 Subject: [PATCH 04/14] Forms: reframe visibility-disable rationale to match verified findings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The per-viewport "Hide on…" option is the part that isn't honored (and on a required field can't be made safe); "hide everywhere" does work for fields, but the GB control bundles both under one supports boolean, so we disable it wholesale on fields/inputs as an interim. Comment/changelog wording only — no functional change. Labels untouched. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../fix-forms-disable-field-visibility-control | 2 +- .../contact-form/class-contact-form-block.php | 17 ++++++++++------- .../packages/forms/src/blocks/input/index.js | 5 +++-- .../forms/src/blocks/shared/settings/index.js | 11 +++++++---- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control b/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control index b13642fa0cb9..b4260ca61842 100644 --- a/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control +++ b/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control @@ -1,4 +1,4 @@ Significance: patch Type: fixed -Forms: Disable the block visibility ("Hide on…") control on form fields and inputs, where it had no effect on the frontend. Labels keep their visibility support. +Forms: Disable the block visibility control on form fields and inputs, where the per-viewport "Hide on…" option was not honored on the frontend. Labels keep their visibility support. diff --git a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php index 0fb7e834e73d..6f0eae07c95e 100644 --- a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php +++ b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php @@ -94,13 +94,16 @@ public static function register_block() { /** * Disable the block "visibility" support on form field and input blocks. * - * Device/viewport visibility ("Hide on…") is not honored on the field - * wrapper at render time — the field render pipeline bypasses core's - * render_block visibility filter — so the control would do nothing. We - * disable the support so it does not appear. This mirrors the JS - * registration (shared/settings/index.js and input/index.js). Labels keep - * visibility support (handled separately via labelhiddenbyblockvisibility), - * and the internal field-option-* blocks are left untouched to match JS. + * FORMS-694 (interim). The per-viewport "Hide on…" option is not honored in + * the forms render pipeline — fields flatten to a shortcode and bypass core's + * render_block class injection — and on a required field it cannot be made + * safe (server- and client-side validation are both viewport-blind). "Hide + * everywhere" does work for fields, but the control bundles both modes under + * one boolean, so we disable it wholesale on fields and inputs as an interim. + * This mirrors the JS registration (shared/settings/index.js and + * input/index.js). Labels keep visibility support (full-hide wired via + * labelhiddenbyblockvisibility), and the internal field-option-* blocks are + * left untouched to match JS. Full field visibility is a separate decision. * * @param array $args Block type registration args. * @param string $block_name Block name being registered. diff --git a/projects/packages/forms/src/blocks/input/index.js b/projects/packages/forms/src/blocks/input/index.js index 1e645098fa7a..1a05d7eb3d7c 100644 --- a/projects/packages/forms/src/blocks/input/index.js +++ b/projects/packages/forms/src/blocks/input/index.js @@ -32,8 +32,9 @@ const settings = { supports: { reusable: false, html: false, - // See FORMS-694: device/viewport visibility isn't honored on the field - // wrapper at render, so disable the control on the input too. + // FORMS-694 (interim): disabled on the input for the same reason as the + // field — see shared/settings/index.js. The input is inert in every + // visibility mode (its rendered output is discarded by the field renderer). visibility: false, color: { text: true, diff --git a/projects/packages/forms/src/blocks/shared/settings/index.js b/projects/packages/forms/src/blocks/shared/settings/index.js index e23b9f5a50e8..e597ce2add04 100644 --- a/projects/packages/forms/src/blocks/shared/settings/index.js +++ b/projects/packages/forms/src/blocks/shared/settings/index.js @@ -30,10 +30,13 @@ export default { supports: { reusable: false, html: false, - // Device/viewport visibility ("Hide on…") is not honored on the field - // wrapper at render time, so disable the control on fields to avoid an - // option that does nothing. Labels keep visibility support (handled - // separately via labelhiddenbyblockvisibility). See FORMS-694. + // FORMS-694 (interim): the per-viewport "Hide on…" option isn't honored + // in the forms render pipeline — fields flatten to a shortcode and bypass + // core's render_block class injection — and on a required field it can't + // be made safe (server/client validation are viewport-blind). "Hide + // everywhere" does work, but the control bundles both under one boolean, + // so we disable it wholesale here. Labels keep it (full-hide wired via + // labelhiddenbyblockvisibility). Full field visibility is a separate call. visibility: false, __experimentalExposeControlsToChildren: true, }, From e6396098b0efabbc5863b19e6ca1e05677d77f82 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Mon, 29 Jun 2026 09:54:00 -0300 Subject: [PATCH 05/14] Forms: honor per-viewport label visibility (Hide on mobile/tablet/desktop) Labels kept blockVisibility support but only full-hide was wired; the per-viewport selection was ignored because the field renderer discards the label's own rendered output (where Gutenberg would have added the wp-block-hidden-* classes). Read blockVisibility.viewport in the block->shortcode bridge and add the same wp-block-hidden-{mobile,tablet,desktop} classes to the label the field renderer emits; the matching media-query CSS is already registered by core's render_block visibility filter (label keeps support). Also apply label classes to the 'below' style-variation label for parity. Verified on the frontend: hidden-on-mobile label gets the class and the @media (width <= 480px){.wp-block-hidden-mobile{display:none}} rule is emitted. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../fix-forms-disable-field-visibility-control | 2 +- .../contact-form/class-contact-form-field.php | 2 +- .../contact-form/class-contact-form-plugin.php | 18 ++++++++++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control b/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control index b4260ca61842..6088000811d1 100644 --- a/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control +++ b/projects/packages/forms/changelog/fix-forms-disable-field-visibility-control @@ -1,4 +1,4 @@ Significance: patch Type: fixed -Forms: Disable the block visibility control on form fields and inputs, where the per-viewport "Hide on…" option was not honored on the frontend. Labels keep their visibility support. +Forms: Disable the block visibility control on form fields and inputs, where the per-viewport "Hide on…" option was not honored on the frontend. Labels keep their visibility support and now honor the per-viewport "Hide on…" option too. diff --git a/projects/packages/forms/src/contact-form/class-contact-form-field.php b/projects/packages/forms/src/contact-form/class-contact-form-field.php index 8d70edbc2876..773f57ea196e 100644 --- a/projects/packages/forms/src/contact-form/class-contact-form-field.php +++ b/projects/packages/forms/src/contact-form/class-contact-form-field.php @@ -2554,7 +2554,7 @@ public function render_below_label( $id, $label, $required, $required_field_text return '