diff --git a/CHANGELOG.md b/CHANGELOG.md index 47daa6f..c1649ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix Tree-shaking support ([#1247](https://github.com/tailwindlabs/headlessui/pull/1247)) - Stop propagation on the Popover Button ([#1263](https://github.com/tailwindlabs/headlessui/pull/1263)) - Fix incorrect closing while interacting with third party libraries in `Dialog` component ([#1268](https://github.com/tailwindlabs/headlessui/pull/1268)) +- Resolve `initialFocusRef` correctly ([#1276](https://github.com/tailwindlabs/headlessui/pull/1276)) ### Added diff --git a/packages/@headlessui-vue/src/components/dialog/dialog.test.ts b/packages/@headlessui-vue/src/components/dialog/dialog.test.ts index c1b4aef..8c727fd 100644 --- a/packages/@headlessui-vue/src/components/dialog/dialog.test.ts +++ b/packages/@headlessui-vue/src/components/dialog/dialog.test.ts @@ -698,6 +698,76 @@ describe('Keyboard interactions', () => { assertActiveElement(document.getElementById('a')) }) ) + + it( + 'should be possible to tab around when using the initialFocus ref on a component', + suppressConsoleLogs(async () => { + let CustomComponent = defineComponent({ + name: 'CustomComponent', + setup() { + return () => h('input') + }, + }) + + renderTemplate({ + components: { + CustomComponent, + }, + template: ` +
+ + + Contents + + + +
+ `, + setup() { + let isOpen = ref(false) + let initialFocusRef = ref(null) + return { + isOpen, + initialFocusRef, + setIsOpen(value: boolean) { + isOpen.value = value + }, + toggleOpen() { + isOpen.value = !isOpen.value + }, + } + }, + }) + + assertDialog({ state: DialogState.InvisibleUnmounted }) + + // Open dialog + await click(document.getElementById('trigger')) + + // Verify it is open + assertDialog({ + state: DialogState.Visible, + attributes: { id: 'headlessui-dialog-1' }, + }) + + // Verify that the input field is focused + assertActiveElement(document.getElementById('b')) + + // Verify that we can tab around + await press(Keys.Tab) + assertActiveElement(document.getElementById('a')) + + // Verify that we can tab around + await press(Keys.Tab) + assertActiveElement(document.getElementById('b')) + + // Verify that we can tab around + await press(Keys.Tab) + assertActiveElement(document.getElementById('a')) + }) + ) }) }) diff --git a/packages/@headlessui-vue/src/hooks/use-focus-trap.ts b/packages/@headlessui-vue/src/hooks/use-focus-trap.ts index cc16d88..776f4c4 100644 --- a/packages/@headlessui-vue/src/hooks/use-focus-trap.ts +++ b/packages/@headlessui-vue/src/hooks/use-focus-trap.ts @@ -12,6 +12,7 @@ import { Keys } from '../keyboard' import { focusElement, focusIn, Focus, FocusResult } from '../utils/focus-management' import { getOwnerDocument } from '../utils/owner' import { useEventListener } from './use-event-listener' +import { dom } from '../utils/dom' export enum Features { /** No features enabled for the `useFocusTrap` hook. */ @@ -96,10 +97,12 @@ export function useFocusTrap( let containerElement = container.value if (!containerElement) return + let initialFocusElement = dom(options.value.initialFocus) + let activeElement = ownerDocument.value?.activeElement as HTMLElement - if (options.value.initialFocus?.value) { - if (options.value.initialFocus?.value === activeElement) { + if (initialFocusElement) { + if (initialFocusElement === activeElement) { previousActiveElement.value = activeElement return // Initial focus ref is already the active element } @@ -109,8 +112,8 @@ export function useFocusTrap( } // Try to focus the initialFocus ref - if (options.value.initialFocus?.value) { - focusElement(options.value.initialFocus.value) + if (initialFocusElement) { + focusElement(initialFocusElement) } else { if (focusIn(containerElement, Focus.First) === FocusResult.Error) { console.warn('There are no focusable elements inside the ')