forked from sugarforever/chat-ollama
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTheTextarea.vue
74 lines (65 loc) · 1.71 KB
/
TheTextarea.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<script lang="ts" setup>
import { useEventListener } from '@vueuse/core'
export type SubmitMode = 'enter' | 'shift-enter'
const emits = defineEmits<{
submit: []
focus: []
blur: []
}>()
const props = defineProps<{
maxRows: number
minRows: number
submitMode: SubmitMode
}>()
const value = defineModel<string>({ required: true })
const textareaRef = shallowRef()
const rows = computed(() => {
const r = Math.min(props.maxRows, (value.value.match(/\n/g) || []).length + 1)
return Math.max(props.minRows, r)
})
const composing = ref(false)
useEventListener(textareaRef, 'compositionstart', () => {
composing.value = true
})
useEventListener(textareaRef, 'compositionend', () => {
composing.value = false
})
function onEnter(e: KeyboardEvent) {
if (composing.value) return
e.preventDefault()
if (props.submitMode === 'enter') {
if (e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
value.value += '\n'
} else if (!e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
onSubmit()
}
} else {
if (e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
onSubmit()
} else {
value.value += '\n'
}
}
}
function onSubmit() {
const event = new Event('submit', {
bubbles: true,
cancelable: true,
});
getFormElement(textareaRef.value.$el)?.dispatchEvent(event)
}
function getFormElement(el: HTMLElement | null) {
if (el) {
if (el.tagName === 'FORM') {
return el as HTMLFormElement
} else {
return getFormElement(el.parentElement)
}
}
return null
}
</script>
<template>
<UTextarea ref="textareaRef" v-model="value" :rows="rows" @keydown.enter.prevent="onEnter" @focus="emits('focus')"
@blur="emits('blur')" />
</template>