From aecb7a99c82047036b7607b3c9aea7c51ea3baf5 Mon Sep 17 00:00:00 2001 From: John Leider Date: Thu, 16 Feb 2023 14:56:33 -0600 Subject: [PATCH] refactor(VPicker): implement date calculation locally --- .../src/components/VPicker/VPickerAlt.sass | 6 + .../src/components/VPicker/VPickerAlt.tsx | 143 ++++++++++++++++++ .../vuetify/src/components/VPicker/index.ts | 3 +- 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 packages/vuetify/src/components/VPicker/VPickerAlt.sass create mode 100644 packages/vuetify/src/components/VPicker/VPickerAlt.tsx diff --git a/packages/vuetify/src/components/VPicker/VPickerAlt.sass b/packages/vuetify/src/components/VPicker/VPickerAlt.sass new file mode 100644 index 000000000000..e19b356499a0 --- /dev/null +++ b/packages/vuetify/src/components/VPicker/VPickerAlt.sass @@ -0,0 +1,6 @@ +.v-picker + // + +.v-picker__body + display: flex + flex-wrap: wrap diff --git a/packages/vuetify/src/components/VPicker/VPickerAlt.tsx b/packages/vuetify/src/components/VPicker/VPickerAlt.tsx new file mode 100644 index 000000000000..dda2d8fae563 --- /dev/null +++ b/packages/vuetify/src/components/VPicker/VPickerAlt.tsx @@ -0,0 +1,143 @@ +// Styles +import './VPickerAlt.sass' + +// Composables +import { useDate } from '@/composables/date' + +// Utilities +import { defineComponent, useRender } from '@/util' +import type { PropType } from 'vue' +import { computed } from 'vue' + +export const VPickerAlt = defineComponent({ + name: 'VPickerAlt', + + props: { + displayDate: { + type: Object as PropType, + default: new Date(), + }, + hideAdjacentMonths: Boolean, + landscape: Boolean, + modelValue: { + type: null as unknown as PropType, + default: () => [], + }, + }, + + setup (props, { slots }) { + const { adapter } = useDate() + + const month = computed(() => props.displayDate) + + const weeksInMonth = computed(() => { + const weeks = adapter.value.getWeekArray(month.value) + + const days = weeks.flat() + + // Make sure there's always 6 weeks in month (6 * 7 days) + // But only do it if we're not hiding adjacent months? + const daysInMonth = 6 * 7 + if (days.length < daysInMonth && !props.hideAdjacentMonths) { + const lastDay = days[days.length - 1] + + let week = [] + for (let day = 1; day <= daysInMonth - days.length; day++) { + week.push(adapter.value.addDays(lastDay, day)) + + if (day % 7 === 0) { + weeks.push(week) + week = [] + } + } + } + + return weeks + }) + + const daysInMonth = computed(() => { + const { format, getYear, getMonth, isWithinRange, isSameMonth, isSameDay } = adapter.value + const validDates = props.modelValue.filter(v => !!v) + const isRange = validDates.length > 1 + + const days = weeksInMonth.value.flat() + const today = adapter.value.date() + + const startDate = validDates[0] + const endDate = validDates[1] + + return days.map((date, index) => { + const isStart = isSameDay(date, startDate) + const isEnd = isSameDay(date, endDate) + const isAdjacent = !isSameMonth(date, month.value) + const isSame = validDates.length === 2 && isSameDay(startDate, endDate) + + return { + date, + formatted: adapter.value.format(date, 'keyboardDate'), + year: getYear(date), + month: getMonth(date), + isWeekStart: index % 7 === 0, + isWeekEnd: index % 7 === 6, + isSelected: isStart || isEnd, + isStart, + isEnd, + isToday: isSameDay(date, today), + isAdjacent, + isHidden: isAdjacent && props.hideAdjacentMonths, + inRange: isRange && !isSame && (isStart || (validDates.length === 2 && isWithinRange(date, validDates as [any, any]))), + // isHovered: props.hoverDate === date, + // inHover: hoverRange.value && isWithinRange(date, hoverRange.value), + isHovered: false, + inHover: false, + localized: format(date, 'dayOfMonth'), + } + }) + }) + + useRender(() => ( +
+ { slots.header ? ( +
+ { slots.header() } +
+ ) : undefined} + +
+ { daysInMonth.value.map((item, index) => ( +
+ { slots.day?.({ item, index }) } +
+ )) } + +
+ + { weeksInMonth.value.map((item, index) => ( +
+ { slots.week?.({ item, index }) } +
+ )) } + + { slots.default?.() } +
+ + { slots.actions ? ( +
+ { slots.actions() } +
+ ) : undefined} +
+ )) + + return {} + }, +}) diff --git a/packages/vuetify/src/components/VPicker/index.ts b/packages/vuetify/src/components/VPicker/index.ts index 8d44940a1eb1..29655df41485 100644 --- a/packages/vuetify/src/components/VPicker/index.ts +++ b/packages/vuetify/src/components/VPicker/index.ts @@ -1 +1,2 @@ -export * from './VPicker' +export { VPicker } from './VPicker' +export { VPickerAlt } from './VPickerAlt'