Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(components): [calendar] #10163

Merged
merged 2 commits into from Oct 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 9 additions & 3 deletions packages/components/calendar/src/calendar.vue
Expand Up @@ -52,8 +52,9 @@
</template>

<script lang="ts" setup>
import { computed } from 'vue'
import { ElButton, ElButtonGroup } from '@element-plus/components/button'
import { useNamespace } from '@element-plus/hooks'
import { useLocale, useNamespace } from '@element-plus/hooks'

import DateTable from './date-table.vue'
import { useCalendar } from './use-calendar'
Expand All @@ -75,11 +76,16 @@ const {
pickDay,
realSelectedDay,
selectDate,
t,
i18nDate,
validatedRange,
} = useCalendar(props, emit, COMPONENT_NAME)

const { t } = useLocale()

const i18nDate = computed(() => {
const pickedMonth = `el.datepicker.month${date.value.format('M')}`
return `${date.value.year()} ${t('el.datepicker.year')} ${t(pickedMonth)}`
})

ryuhangyeong marked this conversation as resolved.
Show resolved Hide resolved
defineExpose({
/** @description currently selected date */
selectedDay: realSelectedDay,
Expand Down
108 changes: 52 additions & 56 deletions packages/components/calendar/src/use-calendar.ts
Expand Up @@ -8,13 +8,56 @@ import type { ComputedRef, SetupContext } from 'vue'
import type { Dayjs } from 'dayjs'
import type { CalendarDateType, CalendarEmits, CalendarProps } from './calendar'

const adjacentMonth = (start: Dayjs, end: Dayjs): [Dayjs, Dayjs][] => {
const firstMonthLastDay = start.endOf('month')
const lastMonthFirstDay = end.startOf('month')

// Whether the last day of the first month and the first day of the last month is in the same week
const isSameWeek = firstMonthLastDay.isSame(lastMonthFirstDay, 'week')
const lastMonthStartDay = isSameWeek
? lastMonthFirstDay.add(1, 'week')
: lastMonthFirstDay

return [
[start, firstMonthLastDay],
[lastMonthStartDay.startOf('week'), end],
]
}

const threeConsecutiveMonth = (start: Dayjs, end: Dayjs): [Dayjs, Dayjs][] => {
const firstMonthLastDay = start.endOf('month')
const secondMonthFirstDay = start.add(1, 'month').startOf('month')

// Whether the last day of the first month and the second month is in the same week
const secondMonthStartDay = firstMonthLastDay.isSame(
secondMonthFirstDay,
'week'
)
? secondMonthFirstDay.add(1, 'week')
: secondMonthFirstDay

const secondMonthLastDay = secondMonthStartDay.endOf('month')
const lastMonthFirstDay = end.startOf('month')

// Whether the last day of the second month and the last day of the last month is in the same week
const lastMonthStartDay = secondMonthLastDay.isSame(lastMonthFirstDay, 'week')
? lastMonthFirstDay.add(1, 'week')
: lastMonthFirstDay

return [
[start, firstMonthLastDay],
[secondMonthStartDay.startOf('week'), secondMonthLastDay],
[lastMonthStartDay.startOf('week'), end],
]
}

export const useCalendar = (
props: CalendarProps,
emit: SetupContext<CalendarEmits>['emit'],
componentName: string
) => {
const solts = useSlots()
const { t, lang } = useLocale()
const slots = useSlots()
const { lang } = useLocale()

const selectedDay = ref<Dayjs>()
const now = dayjs().locale(lang.value)
Expand Down Expand Up @@ -61,12 +104,10 @@ export const useCalendar = (

const date: ComputedRef<Dayjs> = computed(() => {
if (!props.modelValue) {
if (realSelectedDay.value) {
return realSelectedDay.value
} else if (validatedRange.value.length) {
return validatedRange.value[0][0]
}
return now
return (
realSelectedDay.value ||
(validatedRange.value.length ? validatedRange.value[0][0] : now)
)
} else {
return dayjs(props.modelValue).locale(lang.value)
}
Expand All @@ -76,11 +117,6 @@ export const useCalendar = (
const prevYearDayjs = computed(() => date.value.subtract(1, 'year').date(1))
const nextYearDayjs = computed(() => date.value.add(1, 'year').date(1))

const i18nDate = computed(() => {
const pickedMonth = `el.datepicker.month${date.value.format('M')}`
return `${date.value.year()} ${t('el.datepicker.year')} ${t(pickedMonth)}`
})

// https://github.com/element-plus/element-plus/issues/3155
// Calculate the validate date range according to the start and end dates
const calculateValidatedDateRange = (
Expand All @@ -98,52 +134,14 @@ export const useCalendar = (
}
// Two adjacent months
else if (firstMonth + 1 === lastMonth) {
const firstMonthLastDay = firstDay.endOf('month')
const lastMonthFirstDay = lastDay.startOf('month')

// Whether the last day of the first month and the first day of the last month is in the same week
const isSameWeek = firstMonthLastDay.isSame(lastMonthFirstDay, 'week')
const lastMonthStartDay = isSameWeek
? lastMonthFirstDay.add(1, 'week')
: lastMonthFirstDay

return [
[firstDay, firstMonthLastDay],
[lastMonthStartDay.startOf('week'), lastDay],
]
return adjacentMonth(firstDay, lastDay)
}
// Three consecutive months (compatible: 2021-01-30 to 2021-02-28)
else if (
firstMonth + 2 === lastMonth ||
(firstMonth + 1) % 11 === lastMonth
) {
const firstMonthLastDay = firstDay.endOf('month')
const secondMonthFirstDay = firstDay.add(1, 'month').startOf('month')

// Whether the last day of the first month and the second month is in the same week
const secondMonthStartDay = firstMonthLastDay.isSame(
secondMonthFirstDay,
'week'
)
? secondMonthFirstDay.add(1, 'week')
: secondMonthFirstDay

const secondMonthLastDay = secondMonthStartDay.endOf('month')
const lastMonthFirstDay = lastDay.startOf('month')

// Whether the last day of the second month and the last day of the last month is in the same week
const lastMonthStartDay = secondMonthLastDay.isSame(
lastMonthFirstDay,
'week'
)
? lastMonthFirstDay.add(1, 'week')
: lastMonthFirstDay

return [
[firstDay, firstMonthLastDay],
[secondMonthStartDay.startOf('week'), secondMonthLastDay],
[lastMonthStartDay.startOf('week'), lastDay],
]
return threeConsecutiveMonth(firstDay, lastDay)
}
// Other cases
else {
Expand Down Expand Up @@ -184,7 +182,7 @@ export const useCalendar = (
ref: 'https://element-plus.org/en-US/component/calendar.html#slots',
type: 'Slot',
},
computed(() => !!solts.dateCell)
computed(() => !!slots.dateCell)
)

return {
Expand All @@ -194,7 +192,5 @@ export const useCalendar = (
pickDay,
selectDate,
validatedRange,
t,
i18nDate,
}
}