mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-19 16:17:56 +00:00
fix(channels): allow tabbing out of an empty model input
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
class="flex-1 min-w-[120px] border-none bg-transparent text-sm outline-none placeholder:text-gray-400 dark:text-white"
|
||||
:placeholder="models.length === 0 ? placeholder : ''"
|
||||
@keydown.enter.prevent="addModel"
|
||||
@keydown.tab.prevent="addModel"
|
||||
@keydown.tab="handleTab"
|
||||
@keydown.delete="handleBackspace"
|
||||
@paste="handlePaste"
|
||||
@blur="addModel"
|
||||
@@ -66,6 +66,12 @@ function addModel() {
|
||||
inputValue.value = ''
|
||||
}
|
||||
|
||||
function handleTab(event: KeyboardEvent) {
|
||||
if (!inputValue.value.trim()) return
|
||||
event.preventDefault()
|
||||
addModel()
|
||||
}
|
||||
|
||||
function removeModel(idx: number) {
|
||||
const newModels = [...props.models]
|
||||
newModels.splice(idx, 1)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { enableAutoUnmount, mount } from '@vue/test-utils'
|
||||
import { nextTick } from 'vue'
|
||||
import ModelTagInput from '../ModelTagInput.vue'
|
||||
|
||||
vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key: string) => key }) }))
|
||||
enableAutoUnmount(afterEach)
|
||||
|
||||
function pressTab(input: Element, shiftKey = false) {
|
||||
const event = new KeyboardEvent('keydown', { key: 'Tab', shiftKey, bubbles: true, cancelable: true })
|
||||
input.dispatchEvent(event)
|
||||
return event
|
||||
}
|
||||
|
||||
describe('model tag keyboard navigation', () => {
|
||||
it.each([false, true])('allows leaving an empty input with Tab (shift: %s)', (shift) => {
|
||||
const wrapper = mount(ModelTagInput, { props: { models: ['gpt-4o'] } })
|
||||
expect(pressTab(wrapper.get('input').element, shift).defaultPrevented).toBe(false)
|
||||
expect(wrapper.emitted('update:models')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('allows leaving a whitespace-only input', async () => {
|
||||
const wrapper = mount(ModelTagInput, { props: { models: [] } })
|
||||
await wrapper.get('input').setValue(' ')
|
||||
expect(pressTab(wrapper.get('input').element).defaultPrevented).toBe(false)
|
||||
expect(wrapper.emitted('update:models')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('still commits a pending model with Tab, then allows the next Tab to leave', async () => {
|
||||
const wrapper = mount(ModelTagInput, { props: { models: ['gpt-4o'] } })
|
||||
const input = wrapper.get('input')
|
||||
await input.setValue('gpt-4.1')
|
||||
expect(pressTab(input.element).defaultPrevented).toBe(true)
|
||||
await nextTick()
|
||||
expect(wrapper.emitted('update:models')).toEqual([[['gpt-4o', 'gpt-4.1']]])
|
||||
expect((input.element as HTMLInputElement).value).toBe('')
|
||||
expect(pressTab(input.element).defaultPrevented).toBe(false)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user