Use native date pickers across admin forms
This commit is contained in:
@@ -10,3 +10,17 @@
|
||||
* {
|
||||
font-family: 'DingTalk', sans-serif !important;
|
||||
}
|
||||
|
||||
.native-date-input {
|
||||
color-scheme: light;
|
||||
}
|
||||
|
||||
.dark .native-date-input {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
.native-date-input::-webkit-calendar-picker-indicator {
|
||||
cursor: pointer;
|
||||
min-height: 2.75rem;
|
||||
min-width: 2.75rem;
|
||||
}
|
||||
|
||||
@@ -22,13 +22,17 @@
|
||||
<input
|
||||
:type="type"
|
||||
:value="modelValue ?? ''"
|
||||
:min="inputMin"
|
||||
:max="inputMax"
|
||||
class="block w-full rounded-lg border-0 py-2.5 pl-4 pr-10 transition-all duration-200 focus:ring-2 focus:ring-inset sm:text-sm"
|
||||
:class="[
|
||||
isNativeDateField ? 'native-date-input min-h-12 cursor-pointer' : '',
|
||||
isDarkMode
|
||||
? 'bg-gray-700/50 text-white placeholder-gray-400 focus:ring-indigo-500/50'
|
||||
: 'bg-gray-50 text-gray-900 placeholder-gray-400 focus:ring-indigo-500'
|
||||
]"
|
||||
:placeholder="placeholder"
|
||||
@click="openNativePicker"
|
||||
@input="handleInput"
|
||||
/>
|
||||
<div
|
||||
@@ -41,7 +45,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import { computed, inject } from 'vue'
|
||||
import { CheckIcon } from 'lucide-vue-next'
|
||||
|
||||
const props = withDefaults(
|
||||
@@ -49,7 +53,7 @@ const props = withDefaults(
|
||||
label: string
|
||||
modelValue: string | number | null
|
||||
placeholder?: string
|
||||
type?: 'text' | 'number' | 'datetime-local'
|
||||
type?: 'text' | 'number' | 'date' | 'datetime-local'
|
||||
}>(),
|
||||
{
|
||||
placeholder: '',
|
||||
@@ -62,6 +66,23 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const isDarkMode = inject('isDarkMode')
|
||||
const isNativeDateField = computed(() => props.type === 'date' || props.type === 'datetime-local')
|
||||
const inputMin = computed(() => {
|
||||
if (props.type === 'date') return '1900-01-01'
|
||||
if (props.type === 'datetime-local') return '1900-01-01T00:00'
|
||||
return undefined
|
||||
})
|
||||
const inputMax = computed(() => {
|
||||
if (props.type === 'date') return '2100-12-31'
|
||||
if (props.type === 'datetime-local') return '2100-12-31T23:59'
|
||||
return undefined
|
||||
})
|
||||
|
||||
const openNativePicker = (event: MouseEvent) => {
|
||||
if (!isNativeDateField.value) return
|
||||
const input = event.currentTarget as HTMLInputElement & { showPicker?: () => void }
|
||||
input.showPicker?.()
|
||||
}
|
||||
|
||||
const handleInput = (event: Event) => {
|
||||
const target = event.target as HTMLInputElement
|
||||
|
||||
@@ -252,8 +252,9 @@
|
||||
type="date"
|
||||
min="1900-01-01"
|
||||
max="2100-12-31"
|
||||
class="h-11 rounded-lg border px-3 text-sm"
|
||||
class="native-date-input h-12 min-w-0 flex-1 cursor-pointer rounded-xl border px-3 text-sm sm:flex-none sm:min-w-40"
|
||||
:class="[fieldClass]"
|
||||
@click="openNativeDatePicker"
|
||||
@change="fetchAnalyticsData"
|
||||
/>
|
||||
<input
|
||||
@@ -261,8 +262,9 @@
|
||||
type="date"
|
||||
min="1900-01-01"
|
||||
max="2100-12-31"
|
||||
class="h-11 rounded-lg border px-3 text-sm"
|
||||
class="native-date-input h-12 min-w-0 flex-1 cursor-pointer rounded-xl border px-3 text-sm sm:flex-none sm:min-w-40"
|
||||
:class="[fieldClass]"
|
||||
@click="openNativeDatePicker"
|
||||
@change="fetchAnalyticsData"
|
||||
/>
|
||||
<button
|
||||
@@ -489,6 +491,10 @@ const daysAgo = (days: number) => {
|
||||
date.setDate(date.getDate() - days)
|
||||
return date.toISOString().slice(0, 10)
|
||||
}
|
||||
const openNativeDatePicker = (event: MouseEvent) => {
|
||||
const input = event.currentTarget as HTMLInputElement & { showPicker?: () => void }
|
||||
input.showPicker?.()
|
||||
}
|
||||
const trendCanvas = ref<InstanceType<typeof SmoothTrendCanvas> | null>(null)
|
||||
const analyticsStart = ref(daysAgo(120))
|
||||
const analyticsEnd = ref(today())
|
||||
|
||||
Reference in New Issue
Block a user