refactor(components): [date-picker] month range (#7948)

- Use composable `use-range-picker`.
- Remove duplicated code.

Co-authored-by: JeremyWuuuuu <15975785+JeremyWuuuuu@users.noreply.github.com>
This commit is contained in:
Jeremy 2022-05-30 09:03:05 +08:00 committed by GitHub
parent 21a1c24f58
commit 39e273fbdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -99,23 +99,21 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, inject, ref, toRef, useAttrs, useSlots, watch } from 'vue' import { computed, inject, ref, toRef, watch } from 'vue'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import ElIcon from '@element-plus/components/icon' import ElIcon from '@element-plus/components/icon'
import { useLocale, useNamespace } from '@element-plus/hooks' import { useLocale } from '@element-plus/hooks'
import { isArray, isFunction } from '@element-plus/utils' import { isArray } from '@element-plus/utils'
import { DArrowLeft, DArrowRight } from '@element-plus/icons-vue' import { DArrowLeft, DArrowRight } from '@element-plus/icons-vue'
import { ROOT_PICKER_INJECTION_KEY } from '@element-plus/tokens'
import { import {
panelMonthRangeEmits, panelMonthRangeEmits,
panelMonthRangeProps, panelMonthRangeProps,
} from '../props/panel-month-range' } from '../props/panel-month-range'
import { useMonthRangeHeader } from '../composables/use-month-range-header' import { useMonthRangeHeader } from '../composables/use-month-range-header'
import { useRangePicker } from '../composables/use-range-picker'
import MonthTable from './basic-month-table.vue' import MonthTable from './basic-month-table.vue'
import type { SetupContext } from 'vue'
import type { Dayjs } from 'dayjs' import type { Dayjs } from 'dayjs'
import type { RangeState } from '../props/shared'
defineOptions({ defineOptions({
name: 'DatePickerMonthRange', name: 'DatePickerMonthRange',
@ -123,47 +121,25 @@ defineOptions({
const props = defineProps(panelMonthRangeProps) const props = defineProps(panelMonthRangeProps)
const emit = defineEmits(panelMonthRangeEmits) const emit = defineEmits(panelMonthRangeEmits)
const attrs = useAttrs()
const slots = useSlots()
const { pickerNs: ppNs } = inject(ROOT_PICKER_INJECTION_KEY)!
const drpNs = useNamespace('date-range-picker')
const { lang } = useLocale() const { lang } = useLocale()
const {
minDate,
maxDate,
rangeState,
ppNs,
drpNs,
handleChangeRange,
handleRangeConfirm,
handleShortcutClick,
onSelect,
} = useRangePicker()
const leftDate = ref(dayjs().locale(lang.value)) const leftDate = ref(dayjs().locale(lang.value))
const rightDate = ref(dayjs().locale(lang.value).add(1, 'year')) const rightDate = ref(dayjs().locale(lang.value).add(1, 'year'))
const hasShortcuts = computed(() => !!shortcuts.length) const hasShortcuts = computed(() => !!shortcuts.length)
// FIXME: extract this to `date-picker.ts`
type Shortcut = {
text: string
value: [Date, Date] | (() => [Date, Date])
onClick?: (
ctx: Omit<SetupContext<typeof panelMonthRangeEmits>, 'expose'>
) => void
}
const handleShortcutClick = (shortcut: Shortcut) => {
const shortcutValues = isFunction(shortcut.value)
? shortcut.value()
: shortcut.value
if (shortcutValues) {
emit('pick', [
dayjs(shortcutValues[0]).locale(lang.value),
dayjs(shortcutValues[1]).locale(lang.value),
])
return
}
if (shortcut.onClick) {
shortcut.onClick({
attrs,
slots,
emit,
})
}
}
const { const {
leftPrevYear, leftPrevYear,
rightNextYear, rightNextYear,
@ -183,18 +159,6 @@ const enableYearArrow = computed(() => {
return props.unlinkPanels && rightYear.value > leftYear.value + 1 return props.unlinkPanels && rightYear.value > leftYear.value + 1
}) })
const minDate = ref<Dayjs>()
const maxDate = ref<Dayjs>()
const rangeState = ref<RangeState>({
endDate: null,
selecting: false,
})
const handleChangeRange = (val: RangeState) => {
rangeState.value = val
}
type RangePickValue = { type RangePickValue = {
minDate: Dayjs minDate: Dayjs
maxDate: Dayjs maxDate: Dayjs
@ -214,30 +178,7 @@ const handleRangePick = (val: RangePickValue, close = true) => {
minDate.value = minDate_ minDate.value = minDate_
if (!close) return if (!close) return
handleConfirm() handleRangeConfirm()
}
const isValidValue = (value: [Dayjs | undefined, Dayjs | undefined]) => {
return (
isArray(value) &&
value &&
value[0] &&
value[1] &&
value[0].valueOf() <= value[1].valueOf()
)
}
const handleConfirm = (visible = false) => {
if (isValidValue([minDate.value, maxDate.value])) {
emit('pick', [minDate.value, maxDate.value], visible)
}
}
const onSelect = (selecting: boolean) => {
rangeState.value.selecting = selecting
if (!selecting) {
rangeState.value.endDate = null
}
} }
const formatToString = (days: Dayjs[]) => { const formatToString = (days: Dayjs[]) => {