Extract FocusTarget (fix #4732)

This commit is contained in:
the1812 2024-05-12 13:20:48 +08:00
parent 1899c12f25
commit 8f701e9434
2 changed files with 75 additions and 28 deletions

View File

@ -28,9 +28,9 @@
v-for="(a, index) of actions"
:key="a.key"
:action="a"
@previous-item="previousItem($event, index)"
@next-item="nextItem($event, index)"
@delete-item="onDeleteItem($event, index)"
@previous-item="previousItem()"
@next-item="nextItem()"
@delete-item="onDeleteItem()"
@action="
index === actions.length - 1 && onClearHistory()
onAction(a)
@ -49,12 +49,12 @@
class="suggest-item disabled"
></VLoading>
<ActionItem
v-for="(a, index) of actions"
v-for="a of actions"
:key="a.key"
:action="a"
@previous-item="previousItem($event, index)"
@next-item="nextItem($event, index)"
@delete-item="onDeleteItem($event, index)"
@previous-item="previousItem()"
@next-item="nextItem()"
@delete-item="onDeleteItem()"
@action="onAction(a)"
/>
</div>
@ -66,6 +66,7 @@ import Fuse from 'fuse.js'
import { VIcon, VLoading, VEmpty } from '@/ui'
import { registerAndGetData } from '@/plugins/data'
import { select } from '@/core/spin-query'
import { ascendingSort } from '@/core/utils/sort'
import { matchUrlPattern } from '@/core/utils'
import ActionItem from './ActionItem.vue'
import {
@ -75,7 +76,7 @@ import {
} from './launch-bar-action'
import { searchProvider, search } from './search-provider'
import { historyProvider } from './history-provider'
import { ascendingSort } from '@/core/utils/sort'
import { FocusTarget } from './focus-target'
const [actionProviders] = registerAndGetData(LaunchBarActionProviders, [
searchProvider,
@ -144,10 +145,12 @@ export default Vue.extend({
ActionItem,
},
data() {
const focusTarget = new FocusTarget(0)
return {
recommended,
actions: [],
keyword: '',
focusTarget,
noActions: false,
}
},
@ -160,9 +163,15 @@ export default Vue.extend({
keyword() {
this.getActions()
},
actions() {
this.focusTarget.reset(this.actions.length)
},
},
async mounted() {
this.getActions()
await this.getActions()
this.focusTarget.addEventListener('index-change', () => {
this.handleIndexUpdate()
})
if (!matchUrlPattern(/^https?:\/\/search\.bilibili\.com/)) {
return
}
@ -211,47 +220,47 @@ export default Vue.extend({
if (e.isComposing) {
return
}
this.$refs.list.querySelector('.suggest-item:last-child').focus()
this.focusTarget.previous()
e.preventDefault()
},
handleDown(e: KeyboardEvent) {
if (e.isComposing) {
return
}
this.$refs.list.querySelector('.suggest-item').focus()
this.focusTarget.next()
e.preventDefault()
},
previousItem(element: HTMLElement, index: number) {
if (index === 0) {
this.focus()
} else {
;(element.previousElementSibling as HTMLElement).focus()
handleIndexUpdate() {
if (!this.focusTarget.hasFocus) {
this.focusInput()
return
}
this.focusSuggestItem(this.focusTarget.index + 1)
},
nextItem(element: HTMLElement, index: number) {
const lastItemIndex = this.actions.length - 1
if (index !== lastItemIndex) {
;(element.nextElementSibling as HTMLElement).focus()
} else {
this.focus()
}
previousItem() {
this.focusTarget.previous()
},
nextItem() {
this.focusTarget.next()
},
search,
onDeleteItem(element: HTMLElement, index: number) {
this.previousItem(element, index)
onDeleteItem() {
this.focusTarget.previous()
this.getActions()
},
onClearHistory() {
this.focus()
this.focusInput()
this.getActions()
},
onAction() {
// this.focus()
this.handleSelect()
},
focus() {
focusInput() {
this.$refs.input.focus()
},
focusSuggestItem(nth: number) {
this.$refs.list.querySelector(`.suggest-item:nth-child(${nth})`)?.focus()
},
},
})
</script>

View File

@ -0,0 +1,38 @@
export class FocusTarget extends EventTarget {
/**
* -1: Input Focus
* > -1: Item Focus
*/
private itemIndex = -1
private itemLength = 0
constructor(length: number, index = -1) {
super()
this.itemLength = length
this.index = index
}
get index() {
return this.itemIndex
}
private set index(value: number) {
this.itemIndex = lodash.clamp(value, -1, this.itemLength - 1)
this.dispatchEvent(new CustomEvent('index-change', { detail: this }))
}
get hasFocus() {
return this.itemIndex > -1
}
reset(length: number, index = this.index) {
this.itemLength = length
this.index = index
}
next() {
this.index += 1
console.log(this.index)
}
previous() {
this.index -= 1
console.log(this.index)
}
}