50 lines
1.5 KiB
Vue
50 lines
1.5 KiB
Vue
<script setup>
|
|
import { computed } from 'vue'
|
|
|
|
const props = defineProps({
|
|
id: { type: String, default: 'message' },
|
|
rows: { type: Number, default: 4 },
|
|
modelValue: { type: String, default: '' },
|
|
placeholder: { type: String, default: '' },
|
|
labelClass: { type: String, default: '' },
|
|
error: { type: Boolean, default: false },
|
|
success: { type: Boolean, default: false },
|
|
isDisabled: { type: Boolean, default: false },
|
|
})
|
|
|
|
defineEmits(['update:modelValue'])
|
|
|
|
const borderClass = computed(() => {
|
|
if (props.error) return 'border-danger focus:border-danger focus:ring-1 focus:ring-danger'
|
|
if (props.success) return 'border-success focus:border-success focus:ring-1 focus:ring-success'
|
|
return 'border-gray-200 focus:border-primary focus:ring-1 focus:ring-primary'
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<label
|
|
v-if="$slots.default"
|
|
:for="id"
|
|
:class="['mb-1 block text-xs font-medium text-secondary', labelClass]"
|
|
>
|
|
<slot />
|
|
</label>
|
|
|
|
<textarea
|
|
:id="id"
|
|
:rows="rows"
|
|
:value="modelValue"
|
|
:placeholder="placeholder"
|
|
:disabled="isDisabled"
|
|
:class="[
|
|
'w-full resize-none rounded-lg border bg-white px-3 py-2 text-sm text-dark outline-none transition-colors placeholder:text-gray-400',
|
|
borderClass,
|
|
isDisabled && 'cursor-not-allowed opacity-60 bg-gray-50',
|
|
]"
|
|
v-bind="$attrs"
|
|
@input="$emit('update:modelValue', $event.target.value)"
|
|
/>
|
|
</div>
|
|
</template>
|