Initialer Laravel Commit für BetiX
This commit is contained in:
72
resources/js/components/ui/DatePicker.vue
Normal file
72
resources/js/components/ui/DatePicker.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string; // ISO Date String (YYYY-MM-DD)
|
||||
error?: boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
// Internal state for raw input
|
||||
const inputValue = ref('');
|
||||
|
||||
// Format: YYYY-MM-DD -> DD.MM.YYYY for display
|
||||
const formatDate = (iso: string) => {
|
||||
if (!iso) return '';
|
||||
const [y, m, d] = iso.split('-');
|
||||
return `${d}.${m}.${y}`;
|
||||
};
|
||||
|
||||
// Initialize
|
||||
watch(() => props.modelValue, (val) => {
|
||||
// Only update if the formatted value is different to avoid cursor jumping
|
||||
const formatted = formatDate(val);
|
||||
if (inputValue.value !== formatted && val.length === 10) {
|
||||
inputValue.value = formatted;
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
const onInput = (e: Event) => {
|
||||
let val = (e.target as HTMLInputElement).value.replace(/\D/g, ''); // Remove non-digits
|
||||
|
||||
// Auto-insert dots
|
||||
if (val.length > 2) val = val.slice(0, 2) + '.' + val.slice(2);
|
||||
if (val.length > 5) val = val.slice(0, 5) + '.' + val.slice(5);
|
||||
if (val.length > 10) val = val.slice(0, 10);
|
||||
|
||||
inputValue.value = val;
|
||||
|
||||
// Only emit if full date is entered
|
||||
if (val.length === 10) {
|
||||
const [d, m, y] = val.split('.');
|
||||
// Basic validation
|
||||
const day = parseInt(d);
|
||||
const month = parseInt(m);
|
||||
const year = parseInt(y);
|
||||
|
||||
if (day > 0 && day <= 31 && month > 0 && month <= 12 && year > 1900 && year < 2100) {
|
||||
emit('update:modelValue', `${y}-${m}-${d}`);
|
||||
}
|
||||
} else if (val.length === 0) {
|
||||
emit('update:modelValue', '');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
type="text"
|
||||
:value="inputValue"
|
||||
@input="onInput"
|
||||
placeholder="DD.MM.YYYY"
|
||||
class="flex h-10 w-full rounded-md border bg-[#0a0a0a] px-3 py-2 text-sm text-white shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[#00f2ff] disabled:cursor-not-allowed disabled:opacity-50 placeholder:text-[#444]"
|
||||
:class="error ? 'border-red-500' : 'border-[#151515] hover:border-[#333]'"
|
||||
maxlength="10"
|
||||
/>
|
||||
<div class="absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none text-[#666]">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="4" rx="2" ry="2"/><line x1="16" x2="16" y1="2" y2="6"/><line x1="8" x2="8" y1="2" y2="6"/><line x1="3" x2="21" y1="10" y2="10"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user