diff --git a/packages/docs/src/en/plugins/focus.md b/packages/docs/src/en/plugins/focus.md index c79c81ec6..67d786c0e 100644 --- a/packages/docs/src/en/plugins/focus.md +++ b/packages/docs/src/en/plugins/focus.md @@ -301,6 +301,13 @@ For example: + +#### .noautofocus + +By default, when `x-trap` traps focous within an element, it focuses the first focussable element within that element. This is a sensible default, however there are times where you may want to disable this behavior and not automatically focus any elements when `x-trap` engages. + +By adding `.noautofocus`, Alpine will not automatically focus any elements when trapping focus. + ## $focus diff --git a/packages/focus/src/index.js b/packages/focus/src/index.js index 3e7969901..0d970f266 100644 --- a/packages/focus/src/index.js +++ b/packages/focus/src/index.js @@ -108,9 +108,13 @@ export default function (Alpine) { fallbackFocus: () => el, } - let autofocusEl = el.querySelector('[autofocus]') + if (modifiers.includes('noautofocus')) { + options.initialFocus = false + } else { + let autofocusEl = el.querySelector('[autofocus]') - if (autofocusEl) options.initialFocus = autofocusEl + if (autofocusEl) options.initialFocus = autofocusEl + } let trap = createFocusTrap(el, options) diff --git a/tests/cypress/integration/plugins/focus.spec.js b/tests/cypress/integration/plugins/focus.spec.js index 477354683..155281cb7 100644 --- a/tests/cypress/integration/plugins/focus.spec.js +++ b/tests/cypress/integration/plugins/focus.spec.js @@ -369,3 +369,31 @@ test('focuses element with autofocus', get('#3').should(haveFocus()) } ) + +test('can disable x-trap autofocus with .noautofocus modifier', + [html` +
+ + +
+
+ + + +
+
+
+ `], + ({ get }) => { + get('#1').click() + get('#1').should(haveFocus()) + get('#2').click() + get('#4').should(notHaveFocus()) + cy.focused().tab() + get('#3').should(haveFocus()) + cy.focused().tab({shift: true}) + get('#5').should(haveFocus()) + cy.focused().click() + get('#2').should(haveFocus()) + } +)