Skip to content

[TablePagination] Fix the focus ring on the rows-per-page select and page buttons - #49245

Merged
siriwatknp merged 8 commits into
mui:masterfrom
siriwatknp:worktree-fix-table-pagination-focus-visible
Oct 28, 2026
Merged

siriwatknp merged 8 commits into
mui:masterfrom
siriwatknp:worktree-fix-table-pagination-focus-visible

Conversation

@siriwatknp

@siriwatknp siriwatknp commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Summary

Follow-up to the theme.focusVisible opt-in focus ring. TablePagination had no theme.focusVisible handling, which caused two problems once the theme opted in.

1. The rows-per-page select stacked the ring on top of the grey tint. #48743 removed the built-in action.focus tints on opted-in themes so the two indicators don't overlap. TablePagination styles its own InputBase wrapper, so that change missed it, and the select painted the grey fill under the ring:

Before After
TablePagination select showing both the theme focus ring and a grey action.focus fill TablePagination select showing only the theme focus ring

With theme.focusVisible set, the select now shows only the ring, and only on keyboard focus, like the page buttons next to it. Themes without focusVisible keep the grey tint.

2. The ring on the last page button was cut off. The root has overflow: auto and the toolbar has 2px of right padding. The ring sits 4px outside the button, so the root clipped its right side. In the Data Grid, whose footer is a TablePagination, this made the ring look like it overlapped the panel next to it. The page buttons now draw the ring inside the button, the same as Tab and MenuItem do in clipping containers.

For reviewers

  • Select. The old :focus tint rule lives on a private styled InputBase, outside the components covered in [material-ui] Add theme.focusVisible opt-in keyboard focus ring #48743. It now applies only without theme.focusVisible. With it, the select rings on :focus-visible. The select acts as a toolbar button rather than a form field, so it passes internalDisabledThemeFocusVisible to skip the InputBase ring. InputBase draws that ring on .Mui-focused, which mouse focus also sets. SwitchBase and StepButton already use the same opt-out. slotProps.select.variant bypasses TablePaginationInputBase, so that path keeps the form-field behavior.
  • Page buttons. ButtonBase resets the inset on its own root, so setting it on a parent doesn't reach the buttons. The toolbar sets applyInsetFocusVisible(1) on each ButtonBase inside .actions. I chose this over raising the right padding to 4px, which would shift the layout for opted-in themes.
  • Demo. Added TablePagination to the inner-ring group of the full focus visible demo.

Tests

  • Without theme.focusVisible, the select keeps the grey tint. With it, the tint is gone.
  • Keyboard focus draws the ring on the select and not on the InputBase root. This test fails without internalDisabledThemeFocusVisible.
  • Keyboard focus on "Go to next page" gives a negative outline-offset. This test fails without the inset.

🤖 Generated with Claude Code

https://claude.ai/code/session_019h9V1nPwD85PcW2QZdQznG

@code-infra-dashboard

code-infra-dashboard Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Deploy preview

Bundle size

Bundle Parsed size Gzip size
@mui/material 🔺+145B(+0.03%) 🔺+36B(+0.02%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/private-theming 0B(0.00%) 0B(0.00%)
@mui/system 0B(0.00%) 0B(0.00%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes

Performance

No regressions in 32 benchmarks · ran 4m 35s · details


Check out the code infra dashboard for more information about this PR.

…` is set

The select kept `action.focus` on `:focus` on top of the theme ring, so the
trigger showed two focus indicators. Gate it like the other components the
focus-ring sweep covered (Chip, MenuItem, ListItemButton, PaginationItem, …).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Moj2BxvakH3KEeqxSFWMxD
@siriwatknp
siriwatknp force-pushed the worktree-fix-table-pagination-focus-visible branch from e5ebc96 to e9d82e1 Compare September 30, 2026 05:18
@sai6855
sai6855 requested a balanced review from Copilot September 30, 2026 05:52
sai6855
sai6855 previously approved these changes Sep 30, 2026

@sai6855 sai6855 left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good 👍

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The focused change matches established patterns and has browser coverage for both behavior paths.

Review effort: Balanced
Findings: None

What changed in this PR

Removes the duplicate TablePagination select focus tint when the theme focus ring is enabled.

Changes:

  • Gates the legacy focus background behind !theme.focusVisible.
  • Adds browser tests for both opt-in and default behavior.
File Description
TablePagination.js Conditionally applies the select focus tint.
TablePagination.test.js Verifies focus styling with and without the theme ring.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

`SelectInput` hijacks mousedown to focus the trigger itself, so the browser can
no longer attribute the focus to the pointer and matches `:focus-visible`. Pass
`focusVisible: false` on the two pointer-initiated focus calls.

TablePagination's select is a toolbar button, not a form field, so it now opts
out of the `InputBase` ring (keyed on `.Mui-focused`, which pointer focus also
sets) and rings on `:focus-visible` instead.

The restore after the menu closes still rings — that one is `FocusTrap`, shared
by every modal, and is left for a follow-up.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Moj2BxvakH3KEeqxSFWMxD
@siriwatknp siriwatknp changed the title [TablePagination] Drop the select focus tint when theme.focusVisible is set [Select] Keep the keyboard focus ring off pointer focus, and drop the TablePagination tint Sep 30, 2026
@sai6855
sai6855 dismissed their stale review September 30, 2026 13:13

Failing CI

@zannager zannager added the scope: select Changes related to the select. label Oct 6, 2026
@siriwatknp siriwatknp added needs cherry-pick The PR should be cherry-picked to master after merge. v9.x labels Oct 18, 2026
ZeeshanTamboli and others added 6 commits October 26, 2026 10:57
…t focus change

The Select mousedown focus change had no visible effect: the menu opens in the same step and moves focus to an option before the next frame. The action buttons now inset their ring, so the root's overflow no longer clips the last one.
Calling focus({ focusVisible: false }) leaves Firefox treating every later script focus as pointer focus, which broke focus-visible tests in other files sharing the page. The test now checks that keyboard focus rings the select and not the InputBase root.
@siriwatknp siriwatknp changed the title [Select] Keep the keyboard focus ring off pointer focus, and drop the TablePagination tint [TablePagination] Fix the focus ring on the rows-per-page select and page buttons Oct 27, 2026

@siriwatknp siriwatknp left a comment •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

All addressed in 112a1d0. Thanks 🙏

  1. PR title and description still describe the dropped Select change
    Retitled to [TablePagination] ..., and the description now matches the diff.
  2. nit: code comment on TablePaginationInputBase
    Removed in 112a1d0.

@siriwatknp

Copy link
Copy Markdown
Member Author

Review loop done, both findings are addressed and resolved.

@siriwatknp
siriwatknp merged commit c2f0abd into mui:master Oct 28, 2026
23 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Cherry-pick PRs will be created targeting branches: v9.x

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

Labels

needs cherry-pick The PR should be cherry-picked to master after merge. scope: select Changes related to the select. v9.x

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants