Skip to content

Commit 8925d30

Browse files
web-padawanclaude
andauthored
feat: add setTabFocusEnabled API to Popover (#9208)
## Summary Related to vaadin/web-components#11423 - Adds `Popover#setTabFocusEnabled(boolean)` / `isTabFocusEnabled()` to the Flow wrapper, mapping to the web component's `noTabFocus` property in positive form (default `true`, matching the web component's default of `noTabFocus = false`). - When set to `false`, pressing Tab on the target/sibling skips past the popover and Shift+Tab does not move focus into the popover's last focusable. Has no effect on modal popovers (which use their own focus trap), as documented in the Javadoc. - Mirrors the existing inverted-boolean pattern used for `setCloseOnEsc` / `setCloseOnOutsideClick`. ## Test plan - [x] Unit test `PopoverTest#setTabFocusEnabled_isTabFocusEnabled` covers the default state and toggling in both directions, asserting both the public getter and the underlying `noTabFocus` element property. - [x] `mvn spotless:apply` clean. - [x] `mvn test -pl vaadin-popover-flow-parent/vaadin-popover-flow -Dtest='PopoverTest'` passes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b88af58 commit 8925d30

2 files changed

Lines changed: 53 additions & 0 deletions

File tree

  • vaadin-popover-flow-parent/vaadin-popover-flow/src

vaadin-popover-flow-parent/vaadin-popover-flow/src/main/java/com/vaadin/flow/component/popover/Popover.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,42 @@ public boolean isAutofocus() {
343343
return getElement().getProperty("autofocus", false);
344344
}
345345

346+
/**
347+
* Gets whether the popover's content can be reached via Tab navigation from
348+
* the target or sibling elements.
349+
* <p>
350+
* By default, tab focus into the popover is enabled.
351+
* <p>
352+
* NOTE: this setting has no effect on modal popovers, which use their own
353+
* focus trap.
354+
*
355+
* @return {@code true} if tab focus into the popover is enabled,
356+
* {@code false} otherwise
357+
*/
358+
public boolean isTabFocusEnabled() {
359+
return !getElement().getProperty("noTabFocus", false);
360+
}
361+
362+
/**
363+
* Sets whether the popover's content can be reached via Tab navigation from
364+
* the target or sibling elements. When set to {@code false}, pressing Tab
365+
* on the target skips past the popover, and Shift+Tab does not move focus
366+
* into the popover's last focusable element. Focus still moves out of the
367+
* popover on Tab / Shift+Tab if it was placed inside programmatically.
368+
* <p>
369+
* By default, tab focus into the popover is enabled.
370+
* <p>
371+
* NOTE: this setting has no effect on modal popovers, which use their own
372+
* focus trap.
373+
*
374+
* @param tabFocusEnabled
375+
* {@code true} to allow tab focus into the popover,
376+
* {@code false} to skip the popover in tab order
377+
*/
378+
public void setTabFocusEnabled(boolean tabFocusEnabled) {
379+
getElement().setProperty("noTabFocus", !tabFocusEnabled);
380+
}
381+
346382
/**
347383
* Sets the ARIA role for the popover element, used by screen readers.
348384
*

vaadin-popover-flow-parent/vaadin-popover-flow/src/test/java/com/vaadin/flow/component/popover/PopoverTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,23 @@ void setAutofocus_isAutofocus() {
321321
popover.getElement().getProperty("autofocus", false));
322322
}
323323

324+
@Test
325+
void setTabFocusEnabled_isTabFocusEnabled() {
326+
Assertions.assertTrue(popover.isTabFocusEnabled());
327+
Assertions.assertFalse(
328+
popover.getElement().getProperty("noTabFocus", false));
329+
330+
popover.setTabFocusEnabled(false);
331+
Assertions.assertFalse(popover.isTabFocusEnabled());
332+
Assertions.assertTrue(
333+
popover.getElement().getProperty("noTabFocus", false));
334+
335+
popover.setTabFocusEnabled(true);
336+
Assertions.assertTrue(popover.isTabFocusEnabled());
337+
Assertions.assertFalse(
338+
popover.getElement().getProperty("noTabFocus", false));
339+
}
340+
324341
@Test
325342
void popoverWithContent() {
326343
Div content = new Div();

0 commit comments

Comments
 (0)