KEMBAR78
refactor!: set focus-ring attribute on programmatic focus by web-padawan · Pull Request #10049 · vaadin/web-components · GitHub
Skip to content

Conversation

@web-padawan
Copy link
Member

@web-padawan web-padawan commented Aug 21, 2025

Description

Fixes #437
Fixes #1357

  • Updated logic to set focus-ring attribute when calling focus() programmatically
  • Added support for focus({ focusVisible: false }) to prevent setting focus-ring
  • Changed most of components that have focus() method to pass options object

Notable changes:

  • In vaadin-login-overlay, the username field now has focus-ring unless noAutofocus is set

Type of change

  • Behavior altering change

@web-padawan web-padawan force-pushed the refactor/focus-ring-programmatic-focus branch from f8d7a24 to e6bb9e3 Compare August 21, 2025 10:30
}

super.focus();
this._setFocused(true);
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed _setFocused(true) as the item will call it anyway on receiving focus. Also updated the test to use tabindex="0" on the item element to make it focusable so that focusin would be fired.

@web-padawan web-padawan force-pushed the refactor/focus-ring-programmatic-focus branch 3 times, most recently from e090383 to a2fb326 Compare August 21, 2025 10:47
@jouni
Copy link
Member

jouni commented Aug 21, 2025

Does the focus ring always appear in confirm dialog button? I’d expect it to not appear if the dialog opened as a result of an action I did with the mouse.

But I’m not 100% sure. Maybe it always should, so you know you can just press enter (and that pressing enter will actually trigger the confirmation). Perhaps it’s more about focusing the button in the first place, and we should rather just focus the dialog overlay.

@web-padawan
Copy link
Member Author

Does the focus ring always appear in confirm dialog button? I’d expect it to not appear if the dialog opened as a result of an action I did with the mouse.

I could change to use isKeyboardActive() to keep the current behavior.

@jouni
Copy link
Member

jouni commented Aug 21, 2025

Similarly with Upload: I wouldn't expect the focus ring to appear visibly on the Add File button when removing the last file by clicking with the mouse.

@web-padawan
Copy link
Member Author

web-padawan commented Aug 21, 2025

Updated both confirm-dialog, rich-text-editor and upload accordingly so now they would behave as previously.

@web-padawan web-padawan marked this pull request as ready for review August 21, 2025 12:55
* @override
*/
focus() {
focus(options) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of scope of this PR, just to mention it for completeness sack: flow also has s focus method which would need the overload and probably.. even tho I'm not sure where you wanna draw the line.. because some flow components implement Focusable and are not really your web-components (e.g. native html and so on..) so not sure if that would be the right interface..or your way of implementing it would also cover other elements

https://github.com/vaadin/flow/blob/eda19b9ecd987b16cd499be503deb07c5457875e/flow-server/src/main/java/com/vaadin/flow/component/Focusable.java#L108

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for pointing out. Could you please create a separate issue in Flow? I think some users could also benefit from preventScroll: true.

Copy link
Contributor

Choose a reason for hiding this comment

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

@jouni
Copy link
Member

jouni commented Aug 22, 2025

I’m still unsure about the confirm dialog behavior. @rolfsmeds, opinions? If the confirm button is automatically focused when the dialog is opened, should it have a focus outline? I’m almost leaning towards that. The other option would be to keep the focus on the dialog overlay, not focus the button.

That said, I suppose that’s a separate topic, and not blocking this PR. At least it’s consistent with the overall focus outline behavior, that most often it shouldn't become visible if the user navigates with the mouse.

@knoobie
Copy link
Contributor

knoobie commented Aug 22, 2025

I'm also not 100% sure about confirm dialog. I'm also leaning towards outline focused button (even when opened with mouse).

Reasoning: People should see what ENTER would do.. sometimes it not really clear for people what action is going to be executed when a dialog opens and they use their keyboard to quickly finish their job.

Funny example, MacOS Dialog to confirm git credentials.. even tho I focused "immer erlauben" (allow forever) - pressing enter only executes "Erlauben" (allow once)
grafik

@jouni
Copy link
Member

jouni commented Aug 22, 2025

Yeah, macOS has always had this behavior. The Enter key always triggers the primary/submit action of that particular view/dialog, while the Space key triggers the focused button.

@rolfsmeds
Copy link
Contributor

There's also screen readers to take into account here. The neverending dilemma of where to put focus in a dialog and some already known issues with JAWS..

Adrian Roselli wrote a piece on it just recently: https://adrianroselli.com/2025/06/where-to-put-focus-when-opening-a-modal-dialog.html

@web-padawan
Copy link
Member Author

Let's not change where focus is put and keep focusing submit button. The question is, should it always have focus-ring?

@rolfsmeds
Copy link
Contributor

I'd say yes, for the reasons mentioned above.

@web-padawan web-padawan requested a review from vursen August 25, 2025 07:02
@web-padawan web-padawan force-pushed the refactor/focus-ring-programmatic-focus branch from b97c352 to 8a8522c Compare August 28, 2025 11:13
@web-padawan
Copy link
Member Author

Changed the confirm-dialog to always set focus-ring on the submit button on opening per #10049 (comment)

Copy link
Contributor

@DiegoCardoso DiegoCardoso left a comment

Choose a reason for hiding this comment

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

Should AccordionMixin#focus and DashboardItemMixinClass get the options parameter as well?

@web-padawan web-padawan force-pushed the refactor/focus-ring-programmatic-focus branch from 8a8522c to 801b5fb Compare September 3, 2025 06:41
@web-padawan
Copy link
Member Author

Should AccordionMixin#focus and DashboardItemMixinClass get the options parameter as well?

Done.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Sep 3, 2025

@vaadin-bot
Copy link
Collaborator

This ticket/PR has been released with Vaadin 25.0.0-beta2.

@knoobie
Copy link
Contributor

knoobie commented Oct 23, 2025

@web-padawan this might need an update for tearbench as well. I noticed some of my screenshot comparison tests are failing cause clicking a button triggers programmatical focus.. see https://github.com/vaadin/testbench/blob/f217e0f726f99b7b84d247acfbb19dce23536c4d/vaadin-testbench-shared/src/main/java/com/vaadin/testbench/TestBenchElement.java#L198

@web-padawan
Copy link
Member Author

Oh, that's an unfortunate side effect indeed. I will discuss with the team what to do about it.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[field-base] Add support for focus({ focusVisible: true }) to force setting focus-ring Set focus-ring when focus() called programmatically

6 participants