adding components

This commit is contained in:
2026-06-01 17:09:26 -06:00
parent 79a8720fb0
commit 0b1ab9261e
12 changed files with 681 additions and 0 deletions
+89
View File
@@ -0,0 +1,89 @@
<script setup>
import { computed } from 'vue'
const props = defineProps({
id: { type: String, default: '' },
type: { type: String, default: 'text' },
label: { type: [String, Object],default: '' },
modelValue: { type: String, default: '' },
placeholder: { type: String, default: '' },
size: { type: String, default: 'md' },
error: { type: Boolean, default: false },
success: { type: Boolean, default: false },
isRequired: { type: Boolean, default: false },
isDisabled: { type: Boolean, default: false },
inputClass: { type: String, default: '' },
icon: { type: String, default: '' },
})
defineEmits(['update:modelValue'])
const labelText = computed(() =>
typeof props.label === 'string' ? props.label : props.label?.text ?? ''
)
const labelExtraClass = computed(() =>
typeof props.label === 'object' ? props.label?.class ?? '' : ''
)
const sizes = {
sm: 'py-1.5 text-xs',
md: 'py-2 text-sm',
lg: 'py-2.5 text-base',
}
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'
})
const inputClasses = computed(() => [
'w-full rounded-lg border bg-white text-dark outline-none transition-colors placeholder:text-gray-400',
props.icon ? 'pl-9 pr-3' : 'px-3',
sizes[props.size] ?? sizes.md,
borderClass.value,
props.isDisabled && 'cursor-not-allowed opacity-60 bg-gray-50',
props.inputClass,
])
</script>
<template>
<div>
<label
v-if="labelText"
:for="id"
:class="['mb-1 block text-xs font-medium text-secondary', labelExtraClass]"
>
{{ labelText }}
<span v-if="isRequired" class="text-danger">*</span>
</label>
<div class="relative">
<span
v-if="icon"
class="material-icons pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-base text-secondary"
>
{{ icon }}
</span>
<input
:id="id"
:type="type"
:value="modelValue"
:placeholder="placeholder"
:required="isRequired"
:disabled="isDisabled"
:class="inputClasses"
v-bind="$attrs"
@input="$emit('update:modelValue', $event.target.value)"
/>
</div>
<p v-if="error && typeof error === 'string'" class="mt-1 text-xs text-danger">
{{ error }}
</p>
<p v-if="success && typeof success === 'string'" class="mt-1 text-xs text-success">
{{ success }}
</p>
</div>
</template>