diff --git a/resources/js/components/ui/Listing/Search.vue b/resources/js/components/ui/Listing/Search.vue index 5ec400cfba..3bae2bbcac 100644 --- a/resources/js/components/ui/Listing/Search.vue +++ b/resources/js/components/ui/Listing/Search.vue @@ -17,7 +17,7 @@ defineExpose({ focus });
props.additionalBreadcrumbs, (newVal) => additionalBreadcrumbs.value provide('layout', { additionalBreadcrumbs, }); + +// Focus management: focus main element if no input has auto-focus +let navigationListener = null; + +function focusMain() { + // Wait for components to mount and autofocus to process + nextTick(() => { + requestAnimationFrame(() => { + setTimeout(() => { + // If an input is already focused, we're done + if (document.activeElement?.matches('input, textarea, select, [contenteditable]')) { + return; + } + + // Find any input with autofocus attribute (including nested in UI components) + const autofocusInput = document.querySelector('input[autofocus], textarea[autofocus], select[autofocus]') || + document.querySelector('[data-ui-input] input[autofocus]'); + + // If autofocus input exists but isn't focused, focus it manually + if (autofocusInput && document.activeElement !== autofocusInput) { + autofocusInput.focus(); + return; + } + + // Otherwise, focus the content card + if (!autofocusInput) { + document.querySelector('#content-card')?.focus(); + } + }, 100); + }); + }); +} + +onMounted(() => { + navigationListener = router.on('success', focusMain); + focusMain(); +}); + +onUnmounted(() => { + if (navigationListener) { + navigationListener(); + } +});