mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-13 17:05:47 +08:00
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:
parent
b6049dab1c
commit
3c0496f1a8
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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),
|
||||||
|
Loading…
Reference in New Issue
Block a user