Skip to content

A11y: give data tables' checkbox column a real header (table_headers_exists) - #3369

Open
vivi-the-going-merry[bot] wants to merge 5 commits into
masterfrom
fix/issue-6694-table-headers-exists
Open

vivi-the-going-merry[bot] wants to merge 5 commits into
masterfrom
fix/issue-6694-table-headers-exists

Conversation

@vivi-the-going-merry

Copy link
Copy Markdown
Contributor

What was broken

The IBM Equal Access checker's table_headers_exists rule flagged the checkbox-select-all column in Formidable's admin list tables (Forms list, Entries list, etc., rendered via FrmListHelper::print_column_headers()) and the Import/Export page's Export table (classes/views/xml/import_form.php): the header cell for that column was a headerless <td>, even though the column's row cells are already <th scope="row">. A scope attribute on a <td> isn't recognized as a header by assistive tech.

What changed

  • The cb column header cell is now a real <th scope="col"> in both places.
  • FrmListHelper::display() adds role="presentation" to the <table> element when there are zero items (no <thead>/rows rendered), matching the existing has_min_items() gate that already suppressed the header row in that case.
  • Added SCSS overrides (_widefat.scss, _screen-tablet.scss) restating core's own td.check-column font-size/padding as a th.check-column rule scoped to table.widefat (shared by both tables), so switching the tag doesn't change the cell's visual size. Scoping to table.widefat rather than .wp-list-table matters: the Export table doesn't carry wp-list-table, so an earlier version of this fix left it exposed to the pre-existing .frm-white-body table.widefat th { font-size: var(--text-md) } rule — caught in self-review before this PR opened.

Markup/CSS only — no JS, no behavior change beyond the accessibility fix.

How verified

Two new PHPUnit tests render the real markup and assert the header cell is a <th scope="col">, not a <td>:

  • tests/phpunit/forms/test_FrmFormsListHelper.php::test_checkbox_column_header_is_th
  • tests/phpunit/xml/test_FrmXMLController.php::test_export_table_headers_are_th

Confirmed red against the pre-fix markup, green after, against the real local PHPUnit rig. Full forms/entries/xml test groups pass with no regressions. Compiled css/frm_admin.css rebuilt from the SCSS via the project's own webpack css config.

Self-reviewed (correctness/security/reuse/simplification/efficiency/altitude lenses) before opening — the Export-table CSS gap above was caught and fixed in that pass.

Closes Strategy11/formidable-pro#6694

🤖 Generated with Claude Code

…o#6694)

Three admin data tables had no <th>/scope identified: the list-table
checkbox header cell (a <td>, unlike its row cells which are already
<th scope="row">), the empty-state list table (no <thead> at all when
there are zero items), and the import/export form-selection table
(plain <td> header row).

A `scope` attribute on the checkbox header <td> isn't recognized as a
header, so it needed a real <th> - added matching CSS to keep that
cell's layout the same as WP core's own td.check-column styling.
… layout

FrmListHelper::print_column_headers() renders the checkbox column as a
<th> (accessibility fix), unlike core's own list tables which leave it a
<td>. Moves the check-column sizing override from _forms-list.scss (too
narrow a scope) to _widefat.scss so it applies table-wide, and adds the
missing tablet-breakpoint padding-top to match core's td.check-column at
that width.

Parked mid-flight: heartbeat's 1800s wall killed the session before this
could be verified against a live Cypress run or committed. Resuming here
only to land the working tree instead of leaving it stranded — visual/e2e
verification and PR still TODO next pickup.
Confirmed red against the pre-fix markup (<td id='cb'> on the Forms list,
<td class="column-cb check-column"> on the Export table) and green after,
against the real local PHPUnit rig. Also fixes a comment left pointing at
_forms-list.scss after the sizing override moved to _widefat.scss.
Plain string assertions instead of regex where no metacharacters are used,
and drop a redundant not-td assertion already implied by the preceding
positive th assertion on the same cell.
The compensating th.check-column override was scoped to .wp-list-table,
which the Export table's own <table class="widefat ..."> doesn't carry.
That left the pre-existing .frm-white-body table.widefat th rule
(font-size: var(--text-md)) unopposed on the Export table's newly-th cb
header cell -- the exact layout regression the override exists to prevent,
just missed on one of the two tables this fix touches. Rescoped to
table.widefat, which both tables share, instead of .wp-list-table, which
only the Forms list table has. Recompiled css/frm_admin.css from the SCSS
via the css-only webpack config (borrowed node_modules from an existing
scratch clone on the same sass/webpack versions, confirmed via
package.json diff).
@vivi-the-going-merry vivi-the-going-merry Bot added run analysis run e2e tests Run the Cypress end-to-end suite on this PR run tests labels Sep 17, 2026
@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 98f09bd9-e143-4c8d-a53d-0679f09eea64

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@deepsource-io

deepsource-io Bot commented Sep 17, 2026

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in e404085...d0b0582 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
PHP Sep 17, 2026 11:17p.m. Review ↗
JavaScript Sep 17, 2026 11:17p.m. Review ↗

Important

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.


$thead = substr( $html, 0, strpos( $html, '</thead>' ) );

$this->assertMatchesRegularExpression(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Call to an undefined method test_FrmFormsListHelper::assertMatchesRegularExpression()


The method you are trying to call is not defined, which can result in a fatal error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: low run analysis run e2e tests Run the Cypress end-to-end suite on this PR run tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants