refactor(components): [time-picker] setup migration (#7908)

* refactor(components): [time-picker] setup migration

- Migrate panel-month-range to setup

* chore: remove return expression

* chore: change Array.isArray to isArray

* chore: remove required parsedValue
This commit is contained in:
JeremyWuuuuu 2022-05-27 13:55:03 +08:00 committed by GitHub
parent b6049dab1c
commit 3c0496f1a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 208 additions and 208 deletions

View File

@ -95,236 +95,235 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { computed, defineComponent, inject, ref, toRef, watch } from 'vue' import { computed, inject, ref, toRef, useAttrs, useSlots, 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, useNamespace } from '@element-plus/hooks'
import { isArray, isFunction } from '@element-plus/utils'
import { DArrowLeft, DArrowRight } from '@element-plus/icons-vue' import { DArrowLeft, DArrowRight } from '@element-plus/icons-vue'
import { panelMonthRangeProps } from '../props/panel-month-range' import {
panelMonthRangeEmits,
panelMonthRangeProps,
} from '../props/panel-month-range'
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'
export default defineComponent({ defineOptions({
components: { MonthTable, ElIcon, DArrowLeft, DArrowRight }, name: 'DatePickerMonthRange',
})
props: panelMonthRangeProps, const props = defineProps(panelMonthRangeProps)
const emit = defineEmits(panelMonthRangeEmits)
const attrs = useAttrs()
const slots = useSlots()
emits: ['pick', 'set-picker-option'], const ppNs = useNamespace('picker-panel')
const drpNs = useNamespace('date-range-picker')
const { t, lang } = useLocale()
const leftDate = ref(dayjs().locale(lang.value))
const rightDate = ref(dayjs().locale(lang.value).add(1, 'year'))
setup(props, ctx) { const hasShortcuts = computed(() => !!shortcuts.length)
const ppNs = useNamespace('picker-panel')
const drpNs = useNamespace('date-range-picker')
const { t, lang } = useLocale() // FIXME: extract this to `date-picker.ts`
const leftDate = ref(dayjs().locale(lang.value)) type Shortcut = {
const rightDate = ref(dayjs().locale(lang.value).add(1, 'year')) text: string
value: [Date, Date] | (() => [Date, Date])
onClick?: (
ctx: Omit<SetupContext<typeof panelMonthRangeEmits>, 'expose'>
) => void
}
const hasShortcuts = computed(() => !!shortcuts.length) const handleShortcutClick = (shortcut: Shortcut) => {
const shortcutValues = isFunction(shortcut.value)
? shortcut.value()
: shortcut.value
const handleShortcutClick = (shortcut) => { if (shortcutValues) {
const shortcutValues = emit('pick', [
typeof shortcut.value === 'function' ? shortcut.value() : shortcut.value dayjs(shortcutValues[0]).locale(lang.value),
if (shortcutValues) { dayjs(shortcutValues[1]).locale(lang.value),
ctx.emit('pick', [ ])
dayjs(shortcutValues[0]).locale(lang.value), return
dayjs(shortcutValues[1]).locale(lang.value), }
]) if (shortcut.onClick) {
return shortcut.onClick({
} attrs,
if (shortcut.onClick) { slots,
shortcut.onClick(ctx) emit,
}
}
const leftPrevYear = () => {
leftDate.value = leftDate.value.subtract(1, 'year')
if (!props.unlinkPanels) {
rightDate.value = rightDate.value.subtract(1, 'year')
}
}
const rightNextYear = () => {
if (!props.unlinkPanels) {
leftDate.value = leftDate.value.add(1, 'year')
}
rightDate.value = rightDate.value.add(1, 'year')
}
const leftNextYear = () => {
leftDate.value = leftDate.value.add(1, 'year')
}
const rightPrevYear = () => {
rightDate.value = rightDate.value.subtract(1, 'year')
}
const leftLabel = computed(() => {
return `${leftDate.value.year()} ${t('el.datepicker.year')}`
}) })
}
}
const rightLabel = computed(() => { const leftPrevYear = () => {
return `${rightDate.value.year()} ${t('el.datepicker.year')}` leftDate.value = leftDate.value.subtract(1, 'year')
}) if (!props.unlinkPanels) {
rightDate.value = rightDate.value.subtract(1, 'year')
}
}
const leftYear = computed(() => { const rightNextYear = () => {
return leftDate.value.year() if (!props.unlinkPanels) {
}) leftDate.value = leftDate.value.add(1, 'year')
}
rightDate.value = rightDate.value.add(1, 'year')
}
const rightYear = computed(() => { const leftNextYear = () => {
return rightDate.value.year() === leftDate.value.year() leftDate.value = leftDate.value.add(1, 'year')
? leftDate.value.year() + 1 }
: rightDate.value.year()
})
const enableYearArrow = computed(() => { const rightPrevYear = () => {
return props.unlinkPanels && rightYear.value > leftYear.value + 1 rightDate.value = rightDate.value.subtract(1, 'year')
}) }
const leftLabel = computed(() => {
return `${leftDate.value.year()} ${t('el.datepicker.year')}`
})
const minDate = ref(null) const rightLabel = computed(() => {
const maxDate = ref(null) return `${rightDate.value.year()} ${t('el.datepicker.year')}`
})
const rangeState = ref({ const leftYear = computed(() => {
endDate: null, return leftDate.value.year()
selecting: false, })
})
const handleChangeRange = (val) => { const rightYear = computed(() => {
rangeState.value = val return rightDate.value.year() === leftDate.value.year()
? leftDate.value.year() + 1
: rightDate.value.year()
})
const enableYearArrow = computed(() => {
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 = {
minDate: Dayjs
maxDate: Dayjs
}
const handleRangePick = (val: RangePickValue, close = true) => {
// const defaultTime = props.defaultTime || []
// const minDate_ = modifyWithTimeString(val.minDate, defaultTime[0])
// const maxDate_ = modifyWithTimeString(val.maxDate, defaultTime[1])
// todo
const minDate_ = val.minDate
const maxDate_ = val.maxDate
if (maxDate.value === maxDate_ && minDate.value === minDate_) {
return
}
maxDate.value = maxDate_
minDate.value = minDate_
if (!close) return
handleConfirm()
}
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[]) => {
return days.map((day) => day.format(format))
}
const getDefaultValue = () => {
let start: Dayjs
if (isArray(defaultValue.value)) {
const left = dayjs(defaultValue.value[0])
let right = dayjs(defaultValue.value[1])
if (!props.unlinkPanels) {
right = left.add(1, 'year')
} }
return [left, right]
} else if (defaultValue.value) {
start = dayjs(defaultValue.value)
} else {
start = dayjs()
}
start = start.locale(lang.value)
return [start, start.add(1, 'year')]
}
const handleRangePick = (val, close = true) => { // pickerBase.hub.emit('SetPickerOption', ['isValidValue', isValidValue])
// const defaultTime = props.defaultTime || [] emit('set-picker-option', ['formatToString', formatToString])
// const minDate_ = modifyWithTimeString(val.minDate, defaultTime[0]) const pickerBase = inject('EP_PICKER_BASE') as any
// const maxDate_ = modifyWithTimeString(val.maxDate, defaultTime[1]) const { shortcuts, disabledDate, format } = pickerBase.props
// todo const defaultValue = toRef(pickerBase.props, 'defaultValue')
const minDate_ = val.minDate
const maxDate_ = val.maxDate
if (maxDate.value === maxDate_ && minDate.value === minDate_) {
return
}
maxDate.value = maxDate_
minDate.value = minDate_
if (!close) return watch(
handleConfirm() () => defaultValue.value,
} (val) => {
if (val) {
const isValidValue = (value) => { const defaultArr = getDefaultValue()
return ( leftDate.value = defaultArr[0]
Array.isArray(value) && rightDate.value = defaultArr[1]
value &&
value[0] &&
value[1] &&
value[0].valueOf() <= value[1].valueOf()
)
}
const handleConfirm = (visible = false) => {
if (isValidValue([minDate.value, maxDate.value])) {
ctx.emit('pick', [minDate.value, maxDate.value], visible)
}
}
const onSelect = (selecting) => {
rangeState.value.selecting = selecting
if (!selecting) {
rangeState.value.endDate = null
}
}
const formatToString = (value) => {
return value.map((_) => _.format(format))
}
const getDefaultValue = () => {
let start: Dayjs
if (Array.isArray(defaultValue.value)) {
const left = dayjs(defaultValue.value[0])
let right = dayjs(defaultValue.value[1])
if (!props.unlinkPanels) {
right = left.add(1, 'year')
}
return [left, right]
} else if (defaultValue.value) {
start = dayjs(defaultValue.value)
} else {
start = dayjs()
}
start = start.locale(lang.value)
return [start, start.add(1, 'year')]
}
// pickerBase.hub.emit('SetPickerOption', ['isValidValue', isValidValue])
ctx.emit('set-picker-option', ['formatToString', formatToString])
const pickerBase = inject('EP_PICKER_BASE') as any
const { shortcuts, disabledDate, format } = pickerBase.props
const defaultValue = toRef(pickerBase.props, 'defaultValue')
watch(
() => defaultValue.value,
(val) => {
if (val) {
const defaultArr = getDefaultValue()
leftDate.value = defaultArr[0]
rightDate.value = defaultArr[1]
}
},
{ immediate: true }
)
watch(
() => props.parsedValue,
(newVal) => {
if (newVal && newVal.length === 2) {
minDate.value = newVal[0]
maxDate.value = newVal[1]
leftDate.value = minDate.value
if (props.unlinkPanels && maxDate.value) {
const minDateYear = minDate.value.year()
const maxDateYear = maxDate.value.year()
rightDate.value =
minDateYear === maxDateYear
? maxDate.value.add(1, 'year')
: maxDate.value
} else {
rightDate.value = leftDate.value.add(1, 'year')
}
} else {
const defaultArr = getDefaultValue()
minDate.value = null
maxDate.value = null
leftDate.value = defaultArr[0]
rightDate.value = defaultArr[1]
}
},
{ immediate: true }
)
return {
ppNs,
drpNs,
shortcuts,
disabledDate,
onSelect,
handleRangePick,
rangeState,
handleChangeRange,
minDate,
maxDate,
enableYearArrow,
leftLabel,
rightLabel,
leftNextYear,
leftPrevYear,
rightNextYear,
rightPrevYear,
t,
leftDate,
rightDate,
hasShortcuts,
handleShortcutClick,
} }
}, },
}) { immediate: true }
)
watch(
() => props.parsedValue,
(newVal) => {
if (newVal && newVal.length === 2) {
minDate.value = newVal[0]
maxDate.value = newVal[1]
leftDate.value = minDate.value
if (props.unlinkPanels && maxDate.value) {
const minDateYear = minDate.value.year()
const maxDateYear = maxDate.value.year()
rightDate.value =
minDateYear === maxDateYear
? maxDate.value.add(1, 'year')
: maxDate.value
} else {
rightDate.value = leftDate.value.add(1, 'year')
}
} else {
const defaultArr = getDefaultValue()
minDate.value = undefined
maxDate.value = undefined
leftDate.value = defaultArr[0]
rightDate.value = defaultArr[1]
}
},
{ immediate: true }
)
</script> </script>

View File

@ -7,4 +7,6 @@ export const panelMonthRangeProps = buildProps({
...panelRangeSharedProps, ...panelRangeSharedProps,
} as const) } as const)
export const panelMonthRangeEmits = ['pick', 'set-picker-option']
export type PanelMonthRangeProps = ExtractPropTypes<typeof panelMonthRangeProps> export type PanelMonthRangeProps = ExtractPropTypes<typeof panelMonthRangeProps>

View File

@ -3,9 +3,9 @@ import { datePickTypes } from '@element-plus/constants'
import type { Dayjs } from 'dayjs' import type { Dayjs } from 'dayjs'
const selectionModes = ['date', 'dates', 'year', 'month', 'week'] const selectionModes = ['date', 'dates', 'year', 'month', 'week', 'range']
type RangeState = { export type RangeState = {
endDate: null | Dayjs endDate: null | Dayjs
selecting: boolean selecting: boolean
} }
@ -26,7 +26,6 @@ export const datePickerSharedProps = buildProps({
}, },
parsedValue: { parsedValue: {
type: definePropType<Dayjs | Dayjs[]>([Object, Array]), type: definePropType<Dayjs | Dayjs[]>([Object, Array]),
required: true,
}, },
rangeState: { rangeState: {
type: definePropType<RangeState>(Object), type: definePropType<RangeState>(Object),