diff --git a/classes/views/styles/_quick-settings.php b/classes/views/styles/_quick-settings.php
index a86ece648e..9c3f6f71a9 100644
--- a/classes/views/styles/_quick-settings.php
+++ b/classes/views/styles/_quick-settings.php
@@ -161,7 +161,8 @@ class="frm-style-item-heading">
post_content['base_font_size'] ) ? 'for="frm_base_font_size-value"' : ''; ?>
class="frm-style-item-heading">
@@ -207,7 +208,8 @@ class="frm-style-item-heading">
post_content['border_radius'] ) ? 'for="frm_style_qsettings_border_radius-value"' : ''; ?>
class="frm-style-item-heading">
diff --git a/tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js b/tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js
index d0e798715e..3e268ed6d9 100644
--- a/tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js
+++ b/tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js
@@ -30,6 +30,33 @@ describe( 'Style builder labels focus their visible/interactive control', () =>
cy.focused().should( 'have.id', 'frm_fieldset-value' );
} );
+ it( 'A slider label outside Width/Height also drops its focus target once its unit is cleared to "Not set"', () => {
+ cy.intercept( 'POST', '**/admin-ajax.php', req => {
+ if ( req.body?.includes( 'action=frm_change_styling' ) ) {
+ req.alias = 'changeStyling';
+ }
+ } );
+
+ cy.visit( '/wp-admin/admin.php?page=formidable-styles§ion=advanced-settings' );
+ cy.get( '#general-style' ).should( 'have.class', 'open' );
+
+ cy.log( '"Border Width" (frm_fieldset) ships with a measured default, so the label starts wired up' );
+ cy.get( '[data-slider-label-for="frm_fieldset-value"]' ).should( 'have.attr', 'for', 'frm_fieldset-value' );
+
+ cy.log( 'Clearing the unit to "Not set" disables the value input and drops the label\'s focus target' );
+ cy.get( '#frm_fieldset' ).closest( '.frm-slider-component' ).find( '.frm-slider-value select' ).select( '' );
+ cy.wait( '@changeStyling', { timeout: 10000 } );
+ cy.get( '#frm_fieldset-value' ).should( 'be.disabled' );
+ cy.get( '[data-slider-label-for="frm_fieldset-value"]' ).should( 'not.have.attr', 'for' );
+
+ cy.log( 'Choosing a measured unit again re-associates the label with the now-enabled input' );
+ cy.get( '#frm_fieldset' ).closest( '.frm-slider-component' ).find( '.frm-slider-value select' ).select( 'px' );
+ cy.wait( '@changeStyling', { timeout: 10000 } );
+ cy.get( '[data-slider-label-for="frm_fieldset-value"]' ).should( 'have.attr', 'for', 'frm_fieldset-value' );
+ cy.get( '[data-slider-label-for="frm_fieldset-value"]' ).click();
+ cy.focused().should( 'have.id', 'frm_fieldset-value' );
+ } );
+
it( 'A "Width"/"Height" label targets nothing while its unit defaults to "auto", and gets a working focus target once a measured unit is chosen', () => {
cy.intercept( 'POST', '**/admin-ajax.php', req => {
if ( req.body?.includes( 'action=frm_change_styling' ) ) {
From 510d6a442dbc377a96093d2ba9beac0745e37e0e Mon Sep 17 00:00:00 2001
From: "vivi-the-going-merry[bot]"
<308115520+vivi-the-going-merry[bot]@users.noreply.github.com>
Date: Wed, 30 Sep 2026 11:38:47 -0600
Subject: [PATCH 07/14] Give the Styles page first element lookups a 10s
timeout in the label focus spec
CI shard 1 timed out after 4s waiting for the Styles page markup; sliderComponent.cy.js
already uses 10s for the same first lookup.
Co-Authored-By: Claude Sonnet 5.5
---
tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js b/tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js
index 3e268ed6d9..38660fdc13 100644
--- a/tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js
+++ b/tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js
@@ -1,4 +1,7 @@
describe( 'Style builder labels focus their visible/interactive control', () => {
+ // The Styles page is slow to render on a cold CI run, longer than the 4s default.
+ const STYLES_PAGE_TIMEOUT = 10000;
+
beforeEach( () => {
cy.login();
cy.viewport( 1280, 1600 );
@@ -15,14 +18,14 @@ describe( 'Style builder labels focus their visible/interactive control', () =>
// swatch button intentionally reveals it again afterward as WP core's own manual hex
// entry field (color-picker.js `open()` un-hides `.wp-picker-input-wrap`), so asserting
// it stays hidden post-click would fail against WP's own by-design behavior.
- cy.get( '#frm_style_qsettings_submit_bg_color' ).should( 'not.be.visible' );
+ cy.get( '#frm_style_qsettings_submit_bg_color', { timeout: STYLES_PAGE_TIMEOUT } ).should( 'not.be.visible' );
cy.get( 'label[for="frm_style_qsettings_submit_bg_color_visible"]' ).click();
cy.focused().should( 'have.class', 'wp-color-result' );
} );
it( 'Clicking a single-value slider\'s own label focuses the visible number input, not the hidden real input', () => {
cy.visit( '/wp-admin/admin.php?page=formidable-styles§ion=advanced-settings' );
- cy.get( '#general-style' ).should( 'have.class', 'open' );
+ cy.get( '#general-style', { timeout: STYLES_PAGE_TIMEOUT } ).should( 'have.class', 'open' );
// "Border Width" lives directly in the General section, open by default.
cy.get( 'label[for="frm_fieldset-value"]' ).click();
@@ -38,7 +41,7 @@ describe( 'Style builder labels focus their visible/interactive control', () =>
} );
cy.visit( '/wp-admin/admin.php?page=formidable-styles§ion=advanced-settings' );
- cy.get( '#general-style' ).should( 'have.class', 'open' );
+ cy.get( '#general-style', { timeout: STYLES_PAGE_TIMEOUT } ).should( 'have.class', 'open' );
cy.log( '"Border Width" (frm_fieldset) ships with a measured default, so the label starts wired up' );
cy.get( '[data-slider-label-for="frm_fieldset-value"]' ).should( 'have.attr', 'for', 'frm_fieldset-value' );
@@ -65,7 +68,7 @@ describe( 'Style builder labels focus their visible/interactive control', () =>
} );
cy.visit( '/wp-admin/admin.php?page=formidable-styles§ion=advanced-settings' );
- cy.get( '#buttons-style button[aria-label="Buttons"]' ).click();
+ cy.get( '#buttons-style button[aria-label="Buttons"]', { timeout: STYLES_PAGE_TIMEOUT } ).click();
cy.get( '#frm_style_section_buttons-style' ).should( 'be.visible' );
cy.log( 'Width defaults to "auto" out of the box (FrmStyle.php), rendering the value input disabled' );
From cce54fc311035977ab977cc63463dcea5f4222b0 Mon Sep 17 00:00:00 2001
From: Mike Letellier
Date: Thu, 1 Oct 2026 14:45:56 -0300
Subject: [PATCH 08/14] New maybe echo for
---
classes/views/styles/_buttons.php | 10 +++++-----
.../views/styles/_check-box-radio-fields.php | 2 +-
classes/views/styles/_field-colors.php | 4 ++--
classes/views/styles/_field-description.php | 2 +-
classes/views/styles/_field-labels.php | 4 ++--
classes/views/styles/_field-sizes.php | 8 ++++----
classes/views/styles/_form-description.php | 2 +-
classes/views/styles/_form-messages.php | 4 ++--
classes/views/styles/_form-title.php | 2 +-
classes/views/styles/_general.php | 4 ++--
classes/views/styles/_quick-settings.php | 4 ++--
.../components/FrmSliderStyleComponent.php | 19 +++++++++++++++++++
12 files changed, 42 insertions(+), 23 deletions(-)
diff --git a/classes/views/styles/_buttons.php b/classes/views/styles/_buttons.php
index f7791fea78..09f00f4c1e 100644
--- a/classes/views/styles/_buttons.php
+++ b/classes/views/styles/_buttons.php
@@ -54,7 +54,7 @@ class="frm-style-item-heading">
post_content['submit_font_size'] ) ? 'for="frm_submit_font_size-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -91,7 +91,7 @@ class="frm-style-item-heading">
post_content['submit_width'] ) ? 'for="frm_submit_width-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -111,7 +111,7 @@ class="frm-style-item-heading">
post_content['submit_height'] ) ? 'for="frm_submit_height-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -149,7 +149,7 @@ class="frm-style-item-heading">
post_content['submit_border_width'] ) ? 'for="frm_submit_border_width-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -186,7 +186,7 @@ class="frm-style-item-heading">
post_content['submit_border_radius'] ) ? 'for="frm_submit_border_radius-value"' : ''; ?>
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_check-box-radio-fields.php b/classes/views/styles/_check-box-radio-fields.php
index a29a923493..843700f233 100644
--- a/classes/views/styles/_check-box-radio-fields.php
+++ b/classes/views/styles/_check-box-radio-fields.php
@@ -24,7 +24,7 @@ class="frm-style-item-heading">
post_content['check_font_size'] ) ? 'for="frm_check_font_size-value"' : ''; ?>
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_field-colors.php b/classes/views/styles/_field-colors.php
index 6d2e60094d..e68b384ff9 100644
--- a/classes/views/styles/_field-colors.php
+++ b/classes/views/styles/_field-colors.php
@@ -76,7 +76,7 @@ class="frm-style-item-heading">
post_content['field_border_width'] ) ? 'for="frm_field_border_width-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -312,7 +312,7 @@ class="frm-style-item-heading">
post_content['border_width_error'] ) ? 'for="frm_border_width_error-value"' : ''; ?>
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_field-description.php b/classes/views/styles/_field-description.php
index df5ff82c0f..9d8deb46ea 100644
--- a/classes/views/styles/_field-description.php
+++ b/classes/views/styles/_field-description.php
@@ -24,7 +24,7 @@ class="frm-style-item-heading">
post_content['description_font_size'] ) ? 'for="frm_description_font_size-value"' : ''; ?>
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_field-labels.php b/classes/views/styles/_field-labels.php
index 12c47585b8..c3d5fdf46e 100644
--- a/classes/views/styles/_field-labels.php
+++ b/classes/views/styles/_field-labels.php
@@ -38,7 +38,7 @@ class="frm-style-item-heading">
post_content['font_size'] ) ? 'for="frm_font_size-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -109,7 +109,7 @@ class="frm-style-item-heading">
post_content['width'] ) ? 'for="frm_width-value"' : ''; ?>
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_field-sizes.php b/classes/views/styles/_field-sizes.php
index d2d01498d7..a73ebb07d3 100644
--- a/classes/views/styles/_field-sizes.php
+++ b/classes/views/styles/_field-sizes.php
@@ -6,7 +6,7 @@
post_content['field_font_size'] ) ? 'for="frm_field_font_size-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -43,7 +43,7 @@ class="frm-style-item-heading">
post_content['field_height'] ) ? 'for="frm_field_height-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -61,7 +61,7 @@ class="frm-style-item-heading">
post_content['field_width'] ) ? 'for="frm_field_width-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -113,7 +113,7 @@ class="frm-style-item-heading">
post_content['border_radius'] ) ? 'for="frm_border_radius-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -151,7 +151,7 @@ class="frm-style-item-heading">
post_content['error_font_size'] ) ? 'for="frm_error_font_size-value"' : ''; ?>
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_form-title.php b/classes/views/styles/_form-title.php
index 5521fc670e..e4a74c93ba 100644
--- a/classes/views/styles/_form-title.php
+++ b/classes/views/styles/_form-title.php
@@ -24,7 +24,7 @@ class="frm-style-item-heading">
post_content['title_size'] ) ? 'for="frm_title_size-value"' : ''; ?>
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_general.php b/classes/views/styles/_general.php
index 5a2494ca77..dbad303288 100644
--- a/classes/views/styles/_general.php
+++ b/classes/views/styles/_general.php
@@ -66,7 +66,7 @@ class="frm-style-item-heading">
post_content['fieldset'] ) ? 'for="frm_fieldset-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -104,7 +104,7 @@ class="frm-style-item-heading">
post_content['form_width'] ) ? 'for="frm_form_width-value"' : ''; ?>
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_quick-settings.php b/classes/views/styles/_quick-settings.php
index 1704731d05..09a0fbba3b 100644
--- a/classes/views/styles/_quick-settings.php
+++ b/classes/views/styles/_quick-settings.php
@@ -169,7 +169,7 @@ class="frm-style-item-heading">
post_content['base_font_size'] ) ? 'for="frm_base_font_size-value"' : ''; ?>
+
class="frm-style-item-heading">
@@ -213,7 +213,7 @@ class="frm-style-item-heading">
post_content['border_radius'] ) ? 'for="frm_style_qsettings_border_radius-value"' : ''; ?>
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/components/FrmSliderStyleComponent.php b/classes/views/styles/components/FrmSliderStyleComponent.php
index 59938633c5..b0d95b9e0c 100644
--- a/classes/views/styles/components/FrmSliderStyleComponent.php
+++ b/classes/views/styles/components/FrmSliderStyleComponent.php
@@ -384,6 +384,25 @@ public static function is_value_measured( $value ) {
return self::is_measured_unit( self::detect_unit_measurement( $value ) );
}
+ /**
+ * Print a label's for attribute when its slider value input is enabled.
+ *
+ * @since x.x
+ *
+ * @param object $style The style containing the saved values in post_content.
+ * @param string $key The style setting key.
+ * @param string $input_id The slider value input ID.
+ *
+ * @return void
+ */
+ public static function maybe_echo_for( $style, $key, $input_id ) {
+ if ( ! self::is_value_measured( $style->post_content[ $key ] ) ) {
+ return;
+ }
+
+ FrmAppHelper::array_to_html_params( array( 'for' => $input_id ), true );
+ }
+
/**
* Init the field icon
*
From 8510e0b51374168fa8b8f23bae6d49e34af1fa75 Mon Sep 17 00:00:00 2001
From: Mike Letellier
Date: Thu, 1 Oct 2026 14:56:29 -0300
Subject: [PATCH 09/14] Simplify further
---
classes/views/styles/_buttons.php | 15 +++++--------
.../views/styles/_check-box-radio-fields.php | 3 +--
classes/views/styles/_field-colors.php | 6 ++----
classes/views/styles/_field-description.php | 3 +--
classes/views/styles/_field-labels.php | 6 ++----
classes/views/styles/_field-sizes.php | 12 ++++-------
classes/views/styles/_form-description.php | 3 +--
classes/views/styles/_form-messages.php | 6 ++----
classes/views/styles/_form-title.php | 3 +--
classes/views/styles/_general.php | 6 ++----
classes/views/styles/_quick-settings.php | 6 ++----
.../components/FrmSliderStyleComponent.php | 21 +++++++++++++++++++
12 files changed, 44 insertions(+), 46 deletions(-)
diff --git a/classes/views/styles/_buttons.php b/classes/views/styles/_buttons.php
index 09f00f4c1e..7bc5e9c334 100644
--- a/classes/views/styles/_buttons.php
+++ b/classes/views/styles/_buttons.php
@@ -53,8 +53,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
@@ -90,8 +89,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
@@ -110,8 +108,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
@@ -148,8 +145,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
@@ -185,8 +181,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_check-box-radio-fields.php b/classes/views/styles/_check-box-radio-fields.php
index 843700f233..dbcc5b2ef4 100644
--- a/classes/views/styles/_check-box-radio-fields.php
+++ b/classes/views/styles/_check-box-radio-fields.php
@@ -23,8 +23,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_field-colors.php b/classes/views/styles/_field-colors.php
index e68b384ff9..65207af624 100644
--- a/classes/views/styles/_field-colors.php
+++ b/classes/views/styles/_field-colors.php
@@ -75,8 +75,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
@@ -311,8 +310,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_field-description.php b/classes/views/styles/_field-description.php
index 9d8deb46ea..69b3fbc6c1 100644
--- a/classes/views/styles/_field-description.php
+++ b/classes/views/styles/_field-description.php
@@ -23,8 +23,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
diff --git a/classes/views/styles/_field-labels.php b/classes/views/styles/_field-labels.php
index c3d5fdf46e..e5ad974025 100644
--- a/classes/views/styles/_field-labels.php
+++ b/classes/views/styles/_field-labels.php
@@ -37,8 +37,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">
@@ -108,8 +107,7 @@ class="frm-style-item-heading">
+
class="frm-style-item-heading">