You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In Formidable > Styles, several <label for="..."> elements target inputs
that are hidden from the visible/interactive DOM, so clicking the label
doesn't focus anything a user can see:
Color pickers (js/admin/style.js's .wpColorPicker() call): WP's
color picker hides the original input.hex and shows a .wp-color-result
button instead. The button never carried a matching id, so every color
label's for still targeted the now-hidden input.
Single-value sliders (classes/views/styles/components/templates/slider.php):
the visible number input next to the slider handle had no id at all, so
the label's for targeted the slider's hidden "real" value input instead.
What changed
js/admin/style.js: after each color picker initializes, give its .wp-color-result button an {id}_visible id and repoint the matching
label's for to it. One choke point, covers every color picker in every
Style view.
slider.php: give the visible number input an {id}-value id.
Repointed every affected label's for to the new id, for fields whose
value is always a single number (font sizes, widths, heights, border
widths/radii).
Scope - padding/margin sliders excluded
FrmSliderStyleComponent renders either a single input or a 4-way
top/bottom/left/right group depending on the currently saved value
(has-multiple-values = count(explode(' ', $field_value)) > 1), so the
same field (e.g. field_pad/field_margin) can render either shape at
different times. A static for in the calling template can't reliably
target the right element for both shapes - some multi-value labels in this
codebase already leave for off entirely for this reason (e.g. _form-description.php's Margin/Padding labels). Fixing this properly needs
the component itself to own the association (e.g. role="group" + aria-labelledby for the multi-value shape), which is a bigger change than
this PR - left out of scope. Affected ids: frm_field_pad, frm_field_margin, frm_label_padding, frm_submit_margin, frm_submit_padding, frm_description_margin, frm_form_desc_padding, frm_fieldset_padding, frm_style_qsettings_field_margin, frm_style_qsettings_field_pad, plus the two independent_fields margin
sliders in _form-title.php/_form-description.php.
Verification
Added tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js, which clicks
a color-picker label and a single-value-slider label directly and asserts
focus lands on the visible control. Could not run Cypress locally this
session (Docker/wp-env mount gap against a scratch clone under /tmp - ~/Claude/test-sites/formidable/formidable was mid-use by another
in-progress task) - relying on this PR's own CI run (run e2e tests label
added) for the actual red/green signal.
Addresses (partially) #3439 - see Scope section above for what's
intentionally left. Not adding a closing keyword since the padding/margin
part of the issue is still open; will comment on the issue directly instead.
Color pickers: wpColorPicker() hides the original input and shows a
.wp-color-result button instead, but nothing repointed the label's `for`
to follow it - clicking a color swatch's own label did nothing. Fix
this once in style.js for every color picker, right after init.
Single-value sliders: the visible text input next to the slider handle
had no id at all, so every label's `for` targeted the slider's hidden
"real" input instead - same dead-click problem. Give that input an
`{id}-value` id and repoint the corresponding labels.
Scope: only sliders whose value is always a single number (font sizes,
widths, heights, border widths/radii). Padding/margin sliders render as
either a single input or a 4-way group depending on the currently saved
value (FrmSliderStyleComponent::get_values()), so a static `for` can't
target the right element either way - left out of scope, needs the
component itself to own the association rather than the caller.
Fixes#3439 (partial - see PR description for the excluded scope)
Clicks each label directly and asserts focus lands on the visible
control (color-swatch button / slider number input), not the hidden
input the label used to be wired to.
We reviewed changes in efe122d...dcb95ff on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.
Some issues found as part of this review are outside of the diff in this pull request and aren't shown in the inline review comments due to GitHub's API limitations. You can see those issues on the DeepSource dashboard.
AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.
…s original one
style.js repoints the color-picker label's `for` to `{id}_visible` as soon as
wpColorPicker() initializes, which happens before Cypress's query runs - the
test was still selecting the pre-init id, so cy.get() never found it (the
label genuinely no longer carries that attribute value, not a visibility
issue). No production code changed; the slider case in the same file was
unaffected since PHP already renders its label with the final id statically.
Status: parking, CI not yet confirmed on the latest push.
Cypress shard 1 failure (Form Templates/FormTemplates.cy.js) is an unrelated pre-existing flake — different spec entirely, a Cypress spec-bridge visibility timeout, not touched by this PR.
Cypress shard 3 failure was this PR's own new test, styleLabelFocusTargets.cy.js's color-picker case — genuinely red, not a flake: label[for="frm_style_qsettings_submit_bg_color"] was never found. Root cause: style.js's fix repoints that label's for to {id}_visible as soon as wpColorPicker() initializes (which happens before Cypress's query runs), so the test was still asserting against the pre-init id — the label genuinely no longer carries that value, this isn't a visibility timing issue. Fixed the test to select the post-init id instead; no production code changed. Pushed as a771f0d78.
Not yet re-confirmed green — swapping this back to pickup so the next tick verifies CI and closes this out rather than claiming done without having seen it.
…ot after
WP core's own color-picker.js open() intentionally un-hides
.wp-picker-input-wrap (which contains the original input) when the
swatch button is clicked, exposing it as the manual hex-entry field.
Asserting it stays hidden post-click fails against that by-design
behavior; the real regression coverage is that it's hidden before any
interaction and that the click lands focus on the visible swatch
button.
The reason will be displayed to describe this comment to others. Learn more.
Live-verified against this PR's own branch in wp-preview-env (WP admin > Formidable > Styles).
Color-picker case confirmed both by DOM state and by screenshot - clicking the repointed label focuses the visible .wp-color-result swatch button (document.activeElement -> id: frm_style_qsettings_submit_bg_color_visible, class: button wp-color-result wp-picker-open):
Slider case confirmed via DOM/attribute snapshot (not screenshotted - a for/focus-target change on a plain text input isn't pixel-visible either way): clicking label[for="frm_fieldset-value"] moves document.activeElement to { activeId: "frm_fieldset-value", activeTag: "INPUT" }, and the old real input (#frm_fieldset) is confirmed display: none - matches the PR's own new Cypress assertions exactly.
Also independently confirmed via CI log read that the shard-1 Cypress failure is Form Templates/FormTemplates.cy.js, an unrelated pre-existing spec, not this PR's own new test - matches the existing PR comment's diagnosis. Traced DeepSource's 2 flagged PHP-W1066 issues (slider.php:169/172) via git blame to commits from 2026-08-07/2026-09-15, both predating this PR - pre-existing code the diff only shifted via line-count, not a new issue introduced here.
One real gap in the fix itself, inline below - not a regression, but it means the fix doesn't actually apply to 2 of its own target fields in the plugin's default state, with no test coverage to catch it. Couldn't reach that field's section via a stable click in this session to screenshot it directly, so that specific claim rests on the DOM check + source trace in the inline comment, not a screenshot - noting the gap explicitly rather than implying more coverage than was actually exercised.
The reason will be displayed to describe this comment to others. Learn more.
submit_width/submit_height default to 'auto' (classes/models/FrmStyle.php:809-810). FrmSliderStyleComponent::detect_unit_measurement() returns the literal 'auto' for that value, and is_measured_unit('auto') is false (only px/em/% count), so slider.php's new id="...-value" input renders disabled for these two fields by default - live-confirmed on this PR's own branch via playwright-cli eval: document.getElementById('frm_submit_width-value').disabled === true on the plugin's default style.
A <label> click does not focus an associated disabled control (spec behavior, not a bug in this PR's own JS/PHP) - so for="frm_submit_width-value" (here) and for="frm_submit_height-value" (line 111) are no-ops on any brand-new style, which is the plugin's out-of-the-box state. That's the exact class of bug this PR sets out to fix, just still unfixed for these two fields until a user manually switches the unit dropdown off "auto" - and neither new Cypress test exercises an auto-default field, so this ships uncaught.
The PR's own description already documents a matching precedent for a field that can't have a static, reliable focus target - the multi-value padding/margin sliders leave for off entirely rather than pointing at something unreliable. Worth the same treatment here: omit (or JS-conditionally set) for for submit_width/submit_height while their unit is non-measured, rather than leaving it pointed at a disabled input.
The reason will be displayed to describe this comment to others. Learn more.
Fixed: omitted for while the unit is non-measured, added a data-slider-label-for marker, and JS re-associates for once the unit becomes measured (and drops it again on switching back to auto/unset). Verified live via wp-env + Cypress.
…lugin's default auto unit
Both fields default to 'auto' (FrmStyle.php), which renders their slider
value input disabled - a label click never focuses a disabled control, so
the fix's own <label for="..."> was a no-op out of the box. Omit `for` at
render while the unit is non-measured, and re-associate it via JS once a
measured unit is chosen, matching detect_unit_measurement()'s definition of
"measured". Extends styleLabelFocusTargets.cy.js to cover both states.
Fixed the gap: Width/Height default to auto (FrmStyle.php), rendering their value input disabled. Label now omits for while the unit is non-measured (auto or unset), carries a stable data-slider-label-for marker, and slider-component.js re-associates for once a measured unit is chosen (and drops it again if switched back) - closes the loop in both directions, not just the initial render. Compiled js/formidable-settings-components.js hand-patched to match (no JS build step in CI).
Verified locally via a real wp-env + Cypress run (not just CI): both new assertions in styleLabelFocusTargets.cy.js pass, plus the full existing sliderComponent.cy.js suite (6/6, no regressions).
Self-review flagged one real gap not fixed here: the same disabled-input-plus-for defect likely affects ~20 other single-value slider labels in this file family, none of which ship with a non-measured default today. Filed as #3454 rather than expanding this PR's scope.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Re-review at 9591399. Live-verified this commit's fix directly against the PR's own branch (wp-preview-env, WP admin > Formidable > Styles > Buttons), not just read from source:
Default auto state (the exact gap I flagged last round):#frm_submit_width renders auto, #frm_submit_width-value is disabled: true, and [data-slider-label-for="frm_submit_width-value"] has no for attribute (null) — confirmed via DOM eval, not just the screenshot below:
Switching to a measured unit re-associates the label live: selecting px flips inputDisabled to false and restores for="frm_submit_width-value"; clicking the label afterward actually moves document.activeElement to that input ({activeId: "frm_submit_width-value", activeTag: "INPUT"}).
Switching back to auto drops it again, live — not just on next server render: for goes back to null immediately after re-selecting auto, no reload needed.
This matches the new Cypress case (styleLabelFocusTargets.cy.js) exactly, which is also green in this PR's own CI (shard 3) — a second, independent confirmation via a real browser run, not just this session's manual check.
Also checked since my last review:
is_value_measured()/detect_unit_measurement() (source read): auto and unset "" both fail is_measured_unit(), only px/em/% pass — matches the disabled-input condition exactly, and explains why Width/Height specifically needed this (they're the only sliders that ship with a non-measured default today).
Hand-patched js/formidable-settings-components.js (no JS build in CI) checked against slider-component.js line-by-line — the minified updateLabelFocusTarget and its three call sites match the source exactly.
DeepSource's new PHP flag ($style might not be defined, _buttons.php:93/113) is a false positive: $style is used identically dozens of other times in this same file/scope (e.g. line 100, two lines below one of the flagged lines) with no complaint — the only difference is the new lines put the echo inline as a bare tag attribute instead of a full statement. Psalm and PHPStan both pass clean on this same commit.
Scoping the other ~20 single-value slider labels out to #3454 is reasonable: per the PR body, none of them currently ship with a non-measured default, so this specific bug doesn't reproduce there today.
PR #3449 fixed the same defect (a <label for="..."> pointing at a
slider's value input that renders disabled whenever its unit is
non-measured) for Width/Height only, since those are the only two
fields that ship with a non-measured ('auto') default today.
The other ~20 single-value slider labels (font sizes, border widths,
corner radii, etc.) still use a static for="{id}-value" with no
conditional - none of them default to a non-measured unit, so there's
no live bug in the default state, but a user can still clear any
slider's unit to blank ("Not set", which every slider offers) and
disable that field's own label the same way.
Apply the same data-slider-label-for marker + FrmSliderStyleComponent
::is_value_measured() conditional `for` to every remaining plain
for="{id}-value" label in classes/views/styles/. No JS change needed -
style.js's updateLabelFocusTarget() already selects generically by
[data-slider-label-for], so this is template-only.
Extends styleLabelFocusTargets.cy.js with a case covering the "Not
set" unit for a field outside PR #3449's own Width/Height scope
(frm_fieldset, already visited by the existing single-value-slider
test).
Addresses #3454. Branched on top of PR #3449's own branch
(fix/issue-3439-style-label-focus-targets) since the mechanism this
extends doesn't exist on master yet - not opening a PR against master
until #3449 merges.
… 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 <noreply@anthropic.com>
Merged master (no force-push). Conflicts were the Styles view label attributes (kept the slider data-slider-label-for markup, took master's dangling for= removals elsewhere) and js/formidable-settings-components.js (took master's bundle, hand-reapplied updateLabelFocusTarget and its three call sites). js/src and js/admin/style.js merged cleanly.
Verified locally against the merged result: styleLabelFocusTargets.cy.js 4/4 and sliderComponent.cy.js 6/6. CI at 510d6a4: lint, static analysis and PHPUnit green; Cypress shards 0, 2 and 3 green, including both specs above. Shard 1 fails only admin-html-validation.cy.js (form list: '#posts-filter' form has no submit button, wcag/h32), a page this PR does not touch; the same spec also failed in another PR's run today (different error). I can't re-run jobs, so franky-review is not added. Re-run shard 1 and add franky-review if that holds.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Re-review at c44309a. Approve, with four non-blocking notes (three inline, one below). This head is a refactor of the one I approved at 9591399: Mike Letellier's later commits moved the label markup into FrmSliderStyleComponent::style_item_heading() and extended it to 35 slider labels.
Verified live (preview env, Lite at this head, Styles page, quick-settings and advanced-settings views): audited all 100 label.frm-style-item-heading elements against the DOM. Of the 93 labels that carry a for, 83 (advanced view) and 84 (quick view) resolve to an existing, enabled, displayed control. 7 more point at the visually hidden checkbox inside a toggle (existing pattern; Remove Box Shadow is the one this PR touches). Width and Height ship auto and correctly carry no for, only data-slider-label-for. There are no disabled targets and no duplicate *-value ids among the 35 new targets. The remaining non-resolving labels:
Base Font Size on the advanced view: its slider has not_show_in => advanced-settings, so the whole row is hidden (0×0). On the quick view the target exists, is enabled and is visible.
Alignment/Direction (frm_form_align/frm_direction): hidden labels whose for also dangles on master. Not touched here.
Source-verified: I cross-checked all 35 call sites programmatically. Each one's key, input id and the following FrmSliderStyleComponent's id/value key line up; four needed a manual read because those components have a different shape. js/admin/style.js rebuild matches the committed file exactly. js/formidable-settings-components.js has the same updateLabelFocusTarget code as the rebuild. The only differences are 22 lines of minifier and transpile naming noise in code this PR doesn't touch.
CI: PHPUnit (7.4–8.4), Psalm and all 4 Cypress shards pass, including styleLabelFocusTargets.cy.js. At this head PHPCS, PHPStan, ESLint, Rector, CS Fixer, Mago, Stylelint and Oxlint all report "skipping", so no linter ran on the refactor. I ran ESLint on the two hand-written JS files: nothing on changed lines (the one error is a missing sonarjs rule definition in my local plugin set). I didn't lint the PHP; the host has no PHP, though the Styles page rendered on PHP 8.5 with the PR loaded. DeepSource's PHP check is red; I couldn't read its findings from the API.
Not exercised: the multi-value (explode) path in echo_label_attributes() beyond the Buttons "Margin" row's initial render; I didn't switch units on it.
Non-blocking, not inline: no PHPUnit covers the new public statics is_value_measured() and echo_label_attributes(). Cypress touches 3 of the 35 call sites. A small data-provider test ('10px', '12.5', 'auto', '', '10px 5px') is cheap and pins the auto/unset rule the whole PR depends on.
The reason will be displayed to describe this comment to others. Learn more.
maybe_echo_for() has no callers anywhere (grep -rn maybe_echo_for classes js tests returns only this definition). It also differs from echo_label_attributes() by skipping the explode( ' ', ... ) multi-value handling, so it would be wrong for the margin/padding rows if someone used it. Delete it.
Suggested change
/**
* 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.
The reason will be displayed to describe this comment to others. Learn more.
The note about _buttons.php no longer holds. data-slider-label-for is now printed for all 35 slider labels by FrmSliderStyleComponent::echo_label_attributes(), so point there. It also runs to 5 lines where the gotcha fits in 2.
Suggested change
*Keepsavalueinput's <label for="..."> pointed at it only while it is enabled - a label
The reason will be displayed to describe this comment to others. Learn more.
id="remove_box_shadow_active_label" isn't referenced anywhere (no aria-labelledby, JS or CSS selector uses it; the toggle labels itself through aria-label-attr). Drop it.
…rten JS doc
Delete the uncalled FrmSliderStyleComponent::maybe_echo_for(), remove the unreferenced remove_box_shadow_active_label id, and point the updateLabelFocusTarget doc at echo_label_attributes(). PHPUnit coverage for is_value_measured()/echo_label_attributes() still TODO.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Pins is_value_measured() and echo_label_attributes() for px/em/%, unitless, auto, empty and multi-value inputs.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Applied Franky's three inline suggestions (a9a9966) and added the data-provider PHPUnit test from the non-inline note (dcb95ff, tests/phpunit/styles/test_FrmSliderStyleComponent.php, pins is_value_measured and echo_label_attributes incl. 12.5, auto, empty, multi-value). New test green locally (12/12); no force-push, no master merge. Compiled js untouched (doc-comment-only change). Left the DeepSource variable warnings alone.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Variable $style might not be defined
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
The reason will be displayed to describe this comment to others. Learn more.
Re-review at dcb95ff. Approve. The three commits since my c44309a approve resolve all four of my non-blocking notes:
Dead maybe_echo_for() is removed. Nothing in PHP, JS or SCSS references it (grep over the checkout).
The unreferenced remove_box_shadow_active_label id is dropped from _field-colors.php; no reference to it remains anywhere.
The updateLabelFocusTarget docblock now points at FrmSliderStyleComponent::echo_label_attributes(). The change is comment-only in slider-component.js, so the committed bundles have nothing to rebuild.
New test_FrmSliderStyleComponent.php covers is_value_measured() (px/em/%/unitless/auto/empty) and echo_label_attributes() (including 10px 5px and auto 5px).
Test run: I ran the new test's 12 cases outside the WP harness (a stub script loading the real FrmSliderStyleComponent.php, since both methods are pure statics): 0 failures. With is_measured_unit() forced to true, 7 fail (the auto, empty, unitless and auto 5px rows), so the tests do catch the rule the PR depends on. I did not run it through PHPUnit in a WP install.
Not re-checked live: nothing visual changed since c44309a (one id removed from a label that keeps its for, plus comments), so I didn't re-screenshot; my live audit of all 100 style labels at that head stands.
Open:DeepSource: PHP is red at this head. I couldn't see which issues it flags (no annotations or inline comments; the run page doesn't render without a login). Earlier rounds traced its flags to pre-existing lines or a $style false positive, but I haven't confirmed this run's flags are the same ones. Cypress still exercises only 3 of the 35 call sites, which is acceptable now that the PHP logic is unit tested.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was broken
In
Formidable > Styles, several<label for="...">elements target inputsthat are hidden from the visible/interactive DOM, so clicking the label
doesn't focus anything a user can see:
js/admin/style.js's.wpColorPicker()call): WP'scolor picker hides the original
input.hexand shows a.wp-color-resultbutton instead. The button never carried a matching id, so every color
label's
forstill targeted the now-hidden input.classes/views/styles/components/templates/slider.php):the visible number input next to the slider handle had no
idat all, sothe label's
fortargeted the slider's hidden "real" value input instead.What changed
js/admin/style.js: after each color picker initializes, give its.wp-color-resultbutton an{id}_visibleid and repoint the matchinglabel's
forto it. One choke point, covers every color picker in everyStyle view.
slider.php: give the visible number input an{id}-valueid.forto the new id, for fields whosevalue is always a single number (font sizes, widths, heights, border
widths/radii).
Scope - padding/margin sliders excluded
FrmSliderStyleComponentrenders either a single input or a 4-waytop/bottom/left/right group depending on the currently saved value
(
has-multiple-values=count(explode(' ', $field_value)) > 1), so thesame field (e.g.
field_pad/field_margin) can render either shape atdifferent times. A static
forin the calling template can't reliablytarget the right element for both shapes - some multi-value labels in this
codebase already leave
foroff entirely for this reason (e.g._form-description.php's Margin/Padding labels). Fixing this properly needsthe component itself to own the association (e.g.
role="group"+aria-labelledbyfor the multi-value shape), which is a bigger change thanthis PR - left out of scope. Affected ids:
frm_field_pad,frm_field_margin,frm_label_padding,frm_submit_margin,frm_submit_padding,frm_description_margin,frm_form_desc_padding,frm_fieldset_padding,frm_style_qsettings_field_margin,frm_style_qsettings_field_pad, plus the twoindependent_fieldsmarginsliders in
_form-title.php/_form-description.php.Verification
Added
tests/cypress/e2e/Styles/styleLabelFocusTargets.cy.js, which clicksa color-picker label and a single-value-slider label directly and asserts
focus lands on the visible control. Could not run Cypress locally this
session (Docker/wp-env mount gap against a scratch clone under
/tmp-~/Claude/test-sites/formidable/formidablewas mid-use by anotherin-progress task) - relying on this PR's own CI run (
run e2e testslabeladded) for the actual red/green signal.
Addresses (partially) #3439 - see Scope section above for what's
intentionally left. Not adding a closing keyword since the padding/margin
part of the issue is still open; will comment on the issue directly instead.