Skip to content

Commit

Permalink
refactor(VPicker): implement date calculation locally
Browse files Browse the repository at this point in the history
  • Loading branch information
johnleider committed Feb 16, 2023
1 parent e091a78 commit aecb7a9
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 1 deletion.
6 changes: 6 additions & 0 deletions packages/vuetify/src/components/VPicker/VPickerAlt.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.v-picker
//
.v-picker__body
display: flex
flex-wrap: wrap
143 changes: 143 additions & 0 deletions packages/vuetify/src/components/VPicker/VPickerAlt.tsx
Original file line number Diff line number Diff line change
@@ -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<Date>,
default: new Date(),
},
hideAdjacentMonths: Boolean,
landscape: Boolean,
modelValue: {
type: null as unknown as PropType<any[]>,
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(() => (
<div
class={[
'v-picker',
{
'v-picker--landscape': props.landscape,
'v-picker--with-actions': !!slots.actions,
},
]}
{ ...props }
>
{ slots.header ? (
<div class="v-picker__header">
{ slots.header() }
</div>
) : undefined}

<div class="v-picker__body">
{ daysInMonth.value.map((item, index) => (
<div class="v-picker__day">
{ slots.day?.({ item, index }) }
</div>
)) }

<div style="flex: 1 0 100%;" class="my-4"></div>

{ weeksInMonth.value.map((item, index) => (
<div class="v-picker__week">
{ slots.week?.({ item, index }) }
</div>
)) }

{ slots.default?.() }
</div>

{ slots.actions ? (
<div class="v-picker__actions">
{ slots.actions() }
</div>
) : undefined}
</div>
))

return {}
},
})
3 changes: 2 additions & 1 deletion packages/vuetify/src/components/VPicker/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './VPicker'
export { VPicker } from './VPicker'
export { VPickerAlt } from './VPickerAlt'

0 comments on commit aecb7a9

Please sign in to comment.