/
index.ts
45 lines (35 loc) · 1.31 KB
/
index.ts
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
import type { MaybeRef } from '@vueuse/shared'
import type { WatchSource } from 'vue-demi'
import { ref, watch } from 'vue-demi'
import useResizeObserver from '../useResizeObserver'
export interface UseTextareaAutosizeOptions {
/** Textarea element to autosize. */
element?: MaybeRef<HTMLTextAreaElement | undefined>
/** Textarea content. */
input?: MaybeRef<string | undefined>
/** Watch sources that should trigger a textarea resize. */
watch?: WatchSource | Array<WatchSource>
/** Function called when the textarea size changes. */
onResize?: () => void
}
export function useTextareaAutosize(options?: UseTextareaAutosizeOptions) {
const textarea = ref<HTMLTextAreaElement>(options?.element as any)
const input = ref<string>(options?.input as any)
function triggerResize() {
if (!textarea.value)
return
textarea.value!.style.height = '1px'
textarea.value!.style.height = `${textarea.value?.scrollHeight}px`
options?.onResize?.()
}
watch([input, textarea], triggerResize, { immediate: true })
useResizeObserver(textarea, () => triggerResize())
if (options?.watch)
watch(options.watch, triggerResize, { immediate: true, deep: true })
return {
textarea,
input,
triggerResize,
}
}
export type UseTextareaAutosizeReturn = ReturnType<typeof useTextareaAutosize>