|
| 1 | +<template> |
| 2 | + <Input |
| 3 | + ref="input" |
| 4 | + v-if="shortValue" |
| 5 | + class="w-full" |
| 6 | + :modelValue="props.record[props.column.name]" |
| 7 | + :disabled="props.column.editReadonly" |
| 8 | + @update:modelValue="($event) => emit('update:value', $event)" /> |
| 9 | + <textarea |
| 10 | + v-else |
| 11 | + ref="textarea" |
| 12 | + :disabled="props.column.editReadonly" |
| 13 | + class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg block w-full p-2.5 |
| 14 | + dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white focus:ring-lightPrimary focus:border-lightPrimary dark:focus:ring-darkPrimary dark:focus:border-darkPrimary" |
| 15 | + :value="props.record[props.column.name]" |
| 16 | + @input="($event) => { autoResizeTextArea(); emit('update:value', $event.target.value) }" /> |
| 17 | + |
| 18 | +</template> |
| 19 | + |
| 20 | +<script setup lang="ts"> |
| 21 | +import { Input } from "@/afcl"; |
| 22 | +import type { |
| 23 | + AdminForthResourceColumnCommon, |
| 24 | + AdminForthResourceCommon, |
| 25 | + AdminUser, |
| 26 | +} from "@/types/Common"; |
| 27 | +import { computed, defineProps, defineEmits, type Ref, watch, nextTick, ref, onMounted } from "vue"; |
| 28 | +
|
| 29 | +const shortValue: Ref<boolean> = computed(() => (props.record[props.column.name]?.length || 0) < 50); |
| 30 | +
|
| 31 | +const props = defineProps<{ |
| 32 | + column: AdminForthResourceColumnCommon; |
| 33 | + record: any; |
| 34 | + meta: any; |
| 35 | + resource: AdminForthResourceCommon; |
| 36 | + adminUser: AdminUser; |
| 37 | +}>(); |
| 38 | +
|
| 39 | +const emit = defineEmits(["update:value"]); |
| 40 | +
|
| 41 | +const input: Ref<HTMLInputElement | HTMLTextAreaElement | null> = ref(null); |
| 42 | +const textarea: Ref<HTMLInputElement | HTMLTextAreaElement | null> = ref(null); |
| 43 | +
|
| 44 | +// Auto resize function |
| 45 | +const autoResizeTextArea = () => { |
| 46 | + // Use nextTick to ensure the DOM update is done before measuring |
| 47 | + nextTick(() => { |
| 48 | + if (!textarea.value) return |
| 49 | +
|
| 50 | + // Reset the height to shrink if content is removed |
| 51 | + textarea.value.style.height = 'auto' |
| 52 | + // Set it to the scrollHeight to make it grow |
| 53 | + textarea.value.style.height = textarea.value.scrollHeight + 3 + 'px' |
| 54 | + }) |
| 55 | +} |
| 56 | +
|
| 57 | +watch(() => shortValue.value, async () => { |
| 58 | + await nextTick(); |
| 59 | + if (shortValue.value) { |
| 60 | + input.value?.focus(); |
| 61 | + } else { |
| 62 | + textarea.value?.focus(); |
| 63 | + await nextTick(); |
| 64 | + autoResizeTextArea(); |
| 65 | + } |
| 66 | +}); |
| 67 | +
|
| 68 | +
|
| 69 | +onMounted(async () => { |
| 70 | + if (!shortValue.value) { |
| 71 | + await nextTick(); |
| 72 | + autoResizeTextArea(); |
| 73 | + } |
| 74 | +}); |
| 75 | +</script> |
| 76 | + |
0 commit comments