feat: add available range prop to SingleDatePicker for date selection constraints
This commit is contained in:
parent
bd4dd671ef
commit
13a55d7eda
|
@ -8,7 +8,7 @@ const date = ref(new Date())
|
||||||
<template>
|
<template>
|
||||||
<div>{{date.toDateString()}}</div>
|
<div>{{date.toDateString()}}</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<SingleDatePicker v-model="date" localization="zh-CN" @close="() => {}" />
|
<SingleDatePicker :available-range="[new Date(2025, 0, 1), null]" v-model="date" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, defineProps, watch, onMounted, toRefs, getCurrentInstance } from 'vue'
|
import { ref, defineProps, watch, onMounted, toRefs, getCurrentInstance, PropType } from 'vue'
|
||||||
import { generateUniqueId, applyColor, getL10Weekday, getCalendarDates } from '../utils'
|
import { generateUniqueId, applyColor, getL10Weekday, getCalendarDates } from '../utils'
|
||||||
|
|
||||||
interface SingleDatePickerPropsColorScheme {
|
interface SingleDatePickerPropsColorScheme {
|
||||||
|
@ -10,6 +10,8 @@
|
||||||
reversedColor: string
|
reversedColor: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SingleDatePickerPropsAvailableDates = [Date | null, Date | null]
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
colorScheme: {
|
colorScheme: {
|
||||||
type: Object as () => SingleDatePickerPropsColorScheme,
|
type: Object as () => SingleDatePickerPropsColorScheme,
|
||||||
|
@ -29,6 +31,10 @@
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: false,
|
required: false,
|
||||||
|
},
|
||||||
|
availableRange: {
|
||||||
|
type: Array as unknown as PropType<SingleDatePickerPropsAvailableDates>,
|
||||||
|
required: false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -40,6 +46,8 @@
|
||||||
const l10nDays = ref<string[]>([])
|
const l10nDays = ref<string[]>([])
|
||||||
const dates = ref<Date[]>([])
|
const dates = ref<Date[]>([])
|
||||||
const hasCloseListener = getCurrentInstance()?.vnode?.props?.onClose !== undefined
|
const hasCloseListener = getCurrentInstance()?.vnode?.props?.onClose !== undefined
|
||||||
|
const availableRangeStart = ref<Date | null>(null)
|
||||||
|
const availableRangeEnd = ref<Date | null>(null)
|
||||||
|
|
||||||
const { colorScheme, localization } = toRefs(props)
|
const { colorScheme, localization } = toRefs(props)
|
||||||
|
|
||||||
|
@ -51,6 +59,10 @@
|
||||||
dates.value = getCalendarDates(currentMonth.value, currentYear.value)
|
dates.value = getCalendarDates(currentMonth.value, currentYear.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch([props.availableRange], () => {
|
||||||
|
calculateAvailableRange()
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
applyColor(uniqueId, colorScheme.value)
|
applyColor(uniqueId, colorScheme.value)
|
||||||
l10nDays.value = getL10Weekday(localization?.value || navigator.languages[0])
|
l10nDays.value = getL10Weekday(localization?.value || navigator.languages[0])
|
||||||
|
@ -63,6 +75,8 @@
|
||||||
currentYear.value = new Date().getFullYear()
|
currentYear.value = new Date().getFullYear()
|
||||||
}
|
}
|
||||||
dates.value = getCalendarDates(currentMonth.value, currentYear.value)
|
dates.value = getCalendarDates(currentMonth.value, currentYear.value)
|
||||||
|
|
||||||
|
calculateAvailableRange()
|
||||||
})
|
})
|
||||||
|
|
||||||
function goToLastMonth() {
|
function goToLastMonth() {
|
||||||
|
@ -83,8 +97,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function notAvailable(date: Date) {
|
function notAvailable(date: Date): boolean {
|
||||||
return currentMonth.value !== date.getMonth() //TODO: available date ranges
|
return currentMonth.value !== date.getMonth() || (availableRangeStart.value !== null && date < availableRangeStart.value) || (availableRangeEnd.value !== null && date > availableRangeEnd.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectDate(date: Date) {
|
function selectDate(date: Date) {
|
||||||
|
@ -109,6 +123,42 @@
|
||||||
emit('close')
|
emit('close')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function calculateAvailableRange() {
|
||||||
|
if (!props.availableRange) {
|
||||||
|
availableRangeStart.value = null
|
||||||
|
availableRangeEnd.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.availableRange.length !== 2) {
|
||||||
|
console.warn('Invalid availableRange: The length of the array should be 2. The parameter will be ignored.')
|
||||||
|
availableRangeStart.value = null
|
||||||
|
availableRangeEnd.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const [start, end] = props.availableRange
|
||||||
|
|
||||||
|
if (start && end) {
|
||||||
|
if (start > end) {
|
||||||
|
availableRangeStart.value = end
|
||||||
|
availableRangeEnd.value = start
|
||||||
|
} else {
|
||||||
|
availableRangeStart.value = start
|
||||||
|
availableRangeEnd.value = end
|
||||||
|
}
|
||||||
|
} else if (start && !end) {
|
||||||
|
availableRangeStart.value = start
|
||||||
|
availableRangeEnd.value = null
|
||||||
|
} else if (!start && end) {
|
||||||
|
availableRangeStart.value = null
|
||||||
|
availableRangeEnd.value = end
|
||||||
|
} else {
|
||||||
|
availableRangeStart.value = null
|
||||||
|
availableRangeEnd.value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user