fix(frontend): make v-focus directive work with wrapper components
When v-focus is applied to a non-focusable element (like a component wrapper div), it now searches for the first focusable child element (input, select, textarea, or contenteditable) and focuses that instead. This allows v-focus to work correctly with FormField and similar wrapper components.
This commit is contained in:
parent
bad314b5e3
commit
ddd5662d66
|
|
@ -1,6 +1,20 @@
|
|||
import type {Directive} from 'vue'
|
||||
|
||||
const focus = <Directive<HTMLElement,string>>{
|
||||
const FOCUSABLE_TAGS = ['INPUT', 'SELECT', 'TEXTAREA']
|
||||
|
||||
function isFocusable(el: HTMLElement): boolean {
|
||||
return FOCUSABLE_TAGS.includes(el.tagName) || el.isContentEditable
|
||||
}
|
||||
|
||||
function getFocusableElement(el: HTMLElement): HTMLElement | null {
|
||||
if (isFocusable(el)) {
|
||||
return el
|
||||
}
|
||||
// Look for the first focusable child
|
||||
return el.querySelector<HTMLElement>('input, select, textarea, [contenteditable="true"]')
|
||||
}
|
||||
|
||||
const focus = <Directive<HTMLElement, string>>{
|
||||
// When the bound element is inserted into the DOM...
|
||||
mounted(el, {modifiers}) {
|
||||
// Focus the element only if the viewport is big enough
|
||||
|
|
@ -8,7 +22,8 @@ const focus = <Directive<HTMLElement,string>>{
|
|||
// keyboard always pops up and takes half of the available space on the screen.
|
||||
// The threshhold is the same as the breakpoints in css.
|
||||
if (window.innerWidth > 769 || modifiers?.always) {
|
||||
el.focus()
|
||||
const target = getFocusableElement(el)
|
||||
target?.focus()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue