feat(editor): improve desing
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { formatDisplayDate, formatDisplayTime, formatLocalIsoDate, formatLocalIsoTime } from '@/utils/format'
|
||||
|
||||
interface Props {
|
||||
modelValue?: string | null
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string | null]
|
||||
}>()
|
||||
|
||||
const dateValue = ref('')
|
||||
const timeValue = ref('')
|
||||
const dateMenu = ref(false)
|
||||
const timeMenu = ref(false)
|
||||
|
||||
watch(() => props.modelValue, (value) => {
|
||||
const date = value ? new Date(value) : new Date()
|
||||
dateValue.value = formatLocalIsoDate(date)
|
||||
timeValue.value = formatLocalIsoTime(date)
|
||||
}, { immediate: true })
|
||||
|
||||
const emitValue = () => {
|
||||
if (!dateValue.value || !timeValue.value) return
|
||||
emit('update:modelValue', new Date(`${dateValue.value}T${timeValue.value}`).toISOString())
|
||||
}
|
||||
|
||||
const pickerDate = (value: string): Date | null => value ? new Date(`${value}T00:00:00`) : null
|
||||
|
||||
const normalizePickerDate = (value: unknown): string => {
|
||||
const selected = Array.isArray(value) ? value[0] : value
|
||||
const date = selected instanceof Date ? selected : new Date(String(selected))
|
||||
return Number.isNaN(date.getTime()) ? '' : formatLocalIsoDate(date)
|
||||
}
|
||||
|
||||
const selectDate = (value: unknown) => {
|
||||
const date = normalizePickerDate(value)
|
||||
if (date) dateValue.value = date
|
||||
dateMenu.value = false
|
||||
emitValue()
|
||||
}
|
||||
|
||||
watch(timeValue, () => emitValue())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-row dense>
|
||||
<v-col cols="6">
|
||||
<v-menu v-model="dateMenu" :close-on-content-click="false" location="bottom start">
|
||||
<template #activator="{ props: activatorProps }">
|
||||
<v-text-field
|
||||
v-bind="activatorProps"
|
||||
:model-value="formatDisplayDate(dateValue)"
|
||||
label="Date"
|
||||
prepend-inner-icon="mdi-calendar"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
hide-details
|
||||
readonly
|
||||
/>
|
||||
</template>
|
||||
<v-date-picker
|
||||
:model-value="pickerDate(dateValue)"
|
||||
color="primary"
|
||||
show-adjacent-months
|
||||
@update:model-value="selectDate"
|
||||
/>
|
||||
</v-menu>
|
||||
</v-col>
|
||||
<v-col cols="6">
|
||||
<v-menu v-model="timeMenu" :close-on-content-click="false" location="bottom start">
|
||||
<template #activator="{ props: activatorProps }">
|
||||
<v-text-field
|
||||
v-bind="activatorProps"
|
||||
:model-value="formatDisplayTime(timeValue)"
|
||||
label="Time"
|
||||
prepend-inner-icon="mdi-clock-outline"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
hide-details
|
||||
readonly
|
||||
/>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-time-picker v-model="timeValue" color="primary" format="ampm" />
|
||||
<v-card-actions class="justify-end">
|
||||
<v-btn variant="text" @click="timeMenu = false">Done</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
Reference in New Issue
Block a user