|
@@ -2,28 +2,21 @@
|
|
|
<div class="grid gap-1.5">
|
|
<div class="grid gap-1.5">
|
|
|
<label v-if="label" :for="inputId" class="text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
<label v-if="label" :for="inputId" class="text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
|
{{ label }}
|
|
{{ label }}
|
|
|
- <span v-if="required" class="ml-0.5 text-red-500" aria-hidden="true">*</span>
|
|
|
|
|
</label>
|
|
</label>
|
|
|
- <component
|
|
|
|
|
- :is="tag"
|
|
|
|
|
|
|
+ <input
|
|
|
:id="inputId"
|
|
:id="inputId"
|
|
|
v-bind="$attrs"
|
|
v-bind="$attrs"
|
|
|
:value="modelValue"
|
|
:value="modelValue"
|
|
|
- :disabled="disabled"
|
|
|
|
|
- :required="required"
|
|
|
|
|
- :placeholder="placeholder"
|
|
|
|
|
- class="w-full rounded-xl border bg-background px-3 text-sm text-foreground placeholder-gray-400 outline-none transition-colors focus:border-primary dark:placeholder-gray-500"
|
|
|
|
|
:class="[
|
|
:class="[
|
|
|
- tag === 'textarea' ? 'py-2.5 resize-none' : 'py-2',
|
|
|
|
|
|
|
+ 'w-full rounded-xl border bg-background px-3 py-2 text-sm text-foreground placeholder:text-gray-400 outline-none transition-colors focus:ring-2 focus:ring-primary/30 disabled:cursor-not-allowed disabled:opacity-50 dark:placeholder:text-gray-500',
|
|
|
error
|
|
error
|
|
|
- ? 'border-red-300 dark:border-red-700'
|
|
|
|
|
- : 'border-gray-200 dark:border-gray-700',
|
|
|
|
|
- disabled ? 'opacity-60 cursor-not-allowed' : '',
|
|
|
|
|
|
|
+ ? 'border-red-400 focus:border-red-400 dark:border-red-500/60'
|
|
|
|
|
+ : 'border-gray-200 focus:border-primary dark:border-gray-700'
|
|
|
]"
|
|
]"
|
|
|
@input="$emit('update:modelValue', $event.target.value)"
|
|
@input="$emit('update:modelValue', $event.target.value)"
|
|
|
/>
|
|
/>
|
|
|
<p v-if="error" class="text-xs text-red-600 dark:text-red-400">{{ error }}</p>
|
|
<p v-if="error" class="text-xs text-red-600 dark:text-red-400">{{ error }}</p>
|
|
|
- <p v-else-if="hint" class="text-xs text-gray-400 dark:text-gray-500">{{ hint }}</p>
|
|
|
|
|
|
|
+ <p v-else-if="hint" class="text-xs text-gray-500 dark:text-gray-400">{{ hint }}</p>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -35,16 +28,13 @@ defineOptions({ inheritAttrs: false });
|
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
|
modelValue: { type: String, default: "" },
|
|
modelValue: { type: String, default: "" },
|
|
|
label: { type: String, default: "" },
|
|
label: { type: String, default: "" },
|
|
|
- placeholder: { type: String, default: "" },
|
|
|
|
|
- error: { type: String, default: "" },
|
|
|
|
|
hint: { type: String, default: "" },
|
|
hint: { type: String, default: "" },
|
|
|
- tag: { type: String, default: "input" },
|
|
|
|
|
- disabled: { type: Boolean, default: false },
|
|
|
|
|
- required: { type: Boolean, default: false },
|
|
|
|
|
- id: { type: String, default: "" },
|
|
|
|
|
|
|
+ error: { type: String, default: "" },
|
|
|
|
|
+ id: { type: String, default: "" }
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
defineEmits(["update:modelValue"]);
|
|
defineEmits(["update:modelValue"]);
|
|
|
|
|
|
|
|
-const inputId = computed(() => props.id || `base-input-${Math.random().toString(36).slice(2, 7)}`);
|
|
|
|
|
|
|
+let _counter = 0;
|
|
|
|
|
+const inputId = computed(() => props.id || `base-input-${++_counter}`);
|
|
|
</script>
|
|
</script>
|