ai-cut/app/components/base/BaseTextarea.vue

44 lines
1.2 KiB
Vue
Raw Normal View History

2025-12-16 10:08:51 +00:00
<template>
<div class="flex flex-col">
<label v-if="label" :for="textareaId" class="mb-1 text-sm font-medium text-gray-700">
{{ label }}
</label>
<textarea
:id="textareaId"
:value="modelValue"
:placeholder="placeholder"
:disabled="disabled"
:required="required"
:rows="rows"
class="px-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-blue-400 disabled:bg-gray-50 disabled:cursor-not-allowed resize-y transition-all bg-white/90 backdrop-blur-sm text-gray-900 placeholder:text-gray-400"
@input="$emit('update:modelValue', ($event.target as HTMLTextAreaElement).value)"
/>
<span v-if="error" class="mt-1 text-sm text-red-600">{{ error }}</span>
</div>
</template>
<script setup lang="ts">
interface Props {
modelValue: string
label?: string
placeholder?: string
disabled?: boolean
required?: boolean
rows?: number
error?: string
}
const props = withDefaults(defineProps<Props>(), {
disabled: false,
required: false,
rows: 4
})
defineEmits<{
'update:modelValue': [value: string]
}>()
const textareaId = computed(() => `textarea-${Math.random().toString(36).substr(2, 9)}`)
</script>