mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
chore: date-picker-panel tweaks (#21827)
* docs(components): [date-picker-panel] add missing props & make the doc clearer * fix(components): [date-picker-panel] set default time-format & date-format * refactor(components): [date-picker-panel] remove `format` property
This commit is contained in:
@@ -65,10 +65,11 @@ Note, date time locale (month name, first day of the week ...) are also configur
|
||||
| disabled | whether DatePicker is disabled | ^[boolean] | false |
|
||||
| clearable | whether to show clear button | ^[boolean] | true |
|
||||
| type | type of the picker | ^[enum]`'year' \| 'years' \|'month' \| 'months' \| 'date' \| 'dates' \| 'datetime' \| 'week' \| 'datetimerange' \| 'daterange' \| 'monthrange' \| 'yearrange'` | date |
|
||||
| format | format of the displayed value in the input box (in datetime/datetimerange mode) | ^[string] | YYYY-MM-DD |
|
||||
| default-value | optional, default date of the calendar | ^[object]`Date \| [Date, Date]` | — |
|
||||
| default-time | optional, the time value to use when selecting date range | ^[object]`Date \| [Date, Date]` | — |
|
||||
| value-format | optional, format of binding value. If not specified, the binding value will be a Date object | ^[string] | — |
|
||||
| date-format | optional, format of the date displayed in input's inner panel | ^[string] see [date formats](https://day.js.org/docs/en/display/format) | YYYY-MM-DD |
|
||||
| time-format | optional, format of the time displayed in input's inner panel | ^[string] see [date formats](https://day.js.org/docs/en/display/format) | HH:mm:ss |
|
||||
| unlink-panels | unlink two date-panels in range-picker | ^[boolean] | false |
|
||||
| disabled-date | a function determining if a date is disabled with that date as its parameter. Should return a Boolean | ^[Function]`(data: Date) => boolean` | — |
|
||||
| shortcuts | an object array to set shortcut options | ^[object]`Array<{ text: string, value: Date \| Function }>` | [] |
|
||||
|
||||
@@ -99,8 +99,8 @@ datetime-picker/custom-icon
|
||||
| default-value | optional, default date of the calendar | ^[object]`Date \| [Date, Date]` | — |
|
||||
| default-time | the default time value after picking a date. Time `00:00:00` will be used if not specified | ^[object]`Date \| [Date, Date]` | — |
|
||||
| value-format | optional, format of binding value. If not specified, the binding value will be a Date object | ^[string] see [date formats](https://day.js.org/docs/en/display/format) | — |
|
||||
| date-format ^(2.4.0) | optional, format of the date displayed value in TimePicker's dropdown | ^[string] see [date formats](https://day.js.org/docs/en/display/format) | — |
|
||||
| time-format ^(2.4.0) | optional, format of the time displayed value in TimePicker's dropdown | ^[string] see [date formats](https://day.js.org/docs/en/display/format) | — |
|
||||
| date-format ^(2.4.0) | optional, format of the date displayed in input's inner panel | ^[string] see [date formats](https://day.js.org/docs/en/display/format) | YYYY-MM-DD |
|
||||
| time-format ^(2.4.0) | optional, format of the time displayed in input's inner panel | ^[string] see [date formats](https://day.js.org/docs/en/display/format) | HH:mm:ss |
|
||||
| id | same as `id` in native input | ^[string] / ^[object]`[string, string]` | — |
|
||||
| name | same as `name` in native input | ^[string] | — |
|
||||
| unlink-panels | unlink two date-panels in range-picker | ^[boolean] | false |
|
||||
|
||||
@@ -105,16 +105,14 @@ describe('DatePickerPanel', () => {
|
||||
|
||||
describe(':type="datetime" & :type="datetimerange"', () => {
|
||||
describe(':type="datetime"', () => {
|
||||
it('both picker show correct formated value (extract date-format and time-format from format property', async () => {
|
||||
it('dateFormat & timeFormat', async () => {
|
||||
const value = ref(new Date(2018, 2, 5, 10, 15, 24))
|
||||
const format = ref('YYYY/MM/DD HH:mm A')
|
||||
const dateFormat = ref('')
|
||||
const timeFormat = ref('')
|
||||
const dateFormat = ref('YYYY/MM/DD')
|
||||
const timeFormat = ref('HH:mm A')
|
||||
const wrapper = mount(() => (
|
||||
<DatePickerPanel
|
||||
v-model={value.value}
|
||||
type="datetime"
|
||||
format={format.value}
|
||||
dateFormat={dateFormat.value}
|
||||
timeFormat={timeFormat.value}
|
||||
/>
|
||||
@@ -132,7 +130,8 @@ describe('DatePickerPanel', () => {
|
||||
expect(dateInput.value).toBe('2018/03/05')
|
||||
expect(timeInput.value).toBe('10:15 AM')
|
||||
|
||||
format.value = 'MM-DD-YYYY HH a'
|
||||
dateFormat.value = 'MM-DD-YYYY'
|
||||
timeFormat.value = 'HH a'
|
||||
await nextTick()
|
||||
expect(dateInput.value).toBe('03-05-2018')
|
||||
expect(timeInput.value).toBe('10 am')
|
||||
@@ -470,14 +469,13 @@ describe('DatePickerPanel', () => {
|
||||
new Date(2000, 10, 8, 10, 10),
|
||||
new Date(2000, 10, 11, 10, 10),
|
||||
])
|
||||
const dateFormat = ref('')
|
||||
const timeFormat = ref('')
|
||||
const dateFormat = ref('YYYY/MM/DD')
|
||||
const timeFormat = ref('HH:mm A')
|
||||
const wrapper = mount(() => (
|
||||
<DatePickerPanel
|
||||
v-model={value.value}
|
||||
type="datetimerange"
|
||||
default-time={new Date(2020, 1, 1, 1, 1, 1)}
|
||||
format="YYYY/MM/DD HH:mm A"
|
||||
dateFormat={dateFormat.value}
|
||||
timeFormat={timeFormat.value}
|
||||
showFooter
|
||||
|
||||
@@ -226,6 +226,8 @@ import { ClickOutside as vClickOutside } from '@element-plus/directives'
|
||||
import { useLocale, useNamespace } from '@element-plus/hooks'
|
||||
import ElInput from '@element-plus/components/input'
|
||||
import {
|
||||
DEFAULT_FORMATS_DATE,
|
||||
DEFAULT_FORMATS_TIME,
|
||||
PICKER_BASE_INJECTION_KEY,
|
||||
TimePickPanel,
|
||||
extractDateFormat,
|
||||
@@ -276,7 +278,8 @@ const slots = useSlots()
|
||||
const { t, lang } = useLocale()
|
||||
const pickerBase = inject(PICKER_BASE_INJECTION_KEY) as any
|
||||
const isDefaultFormat = inject(
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY,
|
||||
undefined
|
||||
) as any
|
||||
const { shortcuts, disabledDate, cellClassName, defaultTime } = pickerBase.props
|
||||
const defaultValue = toRef(pickerBase.props, 'defaultValue')
|
||||
@@ -576,11 +579,15 @@ const changeToNow = () => {
|
||||
}
|
||||
|
||||
const timeFormat = computed(() => {
|
||||
return props.timeFormat || extractTimeFormat(props.format)
|
||||
return (
|
||||
props.timeFormat || extractTimeFormat(props.format) || DEFAULT_FORMATS_TIME
|
||||
)
|
||||
})
|
||||
|
||||
const dateFormat = computed(() => {
|
||||
return props.dateFormat || extractDateFormat(props.format)
|
||||
return (
|
||||
props.dateFormat || extractDateFormat(props.format) || DEFAULT_FORMATS_DATE
|
||||
)
|
||||
})
|
||||
|
||||
const visibleTime = computed(() => {
|
||||
|
||||
@@ -406,6 +406,8 @@ import { useLocale } from '@element-plus/hooks'
|
||||
import ElButton from '@element-plus/components/button'
|
||||
import ElInput from '@element-plus/components/input'
|
||||
import {
|
||||
DEFAULT_FORMATS_DATE,
|
||||
DEFAULT_FORMATS_TIME,
|
||||
PICKER_BASE_INJECTION_KEY,
|
||||
TimePickPanel,
|
||||
extractDateFormat,
|
||||
@@ -431,6 +433,7 @@ import YearTable from './basic-year-table.vue'
|
||||
import MonthTable from './basic-month-table.vue'
|
||||
import DateTable from './basic-date-table.vue'
|
||||
|
||||
import type { Ref } from 'vue'
|
||||
import type { Dayjs } from 'dayjs'
|
||||
|
||||
type ChangeType = 'min' | 'max'
|
||||
@@ -451,10 +454,11 @@ const unit = 'month'
|
||||
// FIXME: fix the type for ep picker
|
||||
const pickerBase = inject(PICKER_BASE_INJECTION_KEY) as any
|
||||
const isDefaultFormat = inject(
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY,
|
||||
undefined
|
||||
) as any
|
||||
const { disabledDate, cellClassName, defaultTime, clearable } = pickerBase.props
|
||||
const format = toRef(pickerBase.props, 'format')
|
||||
const format: Ref<string | undefined> = toRef(pickerBase.props, 'format')
|
||||
const shortcuts = toRef(pickerBase.props, 'shortcuts')
|
||||
const defaultValue = toRef(pickerBase.props, 'defaultValue')
|
||||
const { lang } = useLocale()
|
||||
@@ -553,11 +557,19 @@ const maxVisibleTime = computed(() => {
|
||||
})
|
||||
|
||||
const timeFormat = computed(() => {
|
||||
return props.timeFormat || extractTimeFormat(format.value)
|
||||
return (
|
||||
props.timeFormat ||
|
||||
extractTimeFormat(format.value || '') ||
|
||||
DEFAULT_FORMATS_TIME
|
||||
)
|
||||
})
|
||||
|
||||
const dateFormat = computed(() => {
|
||||
return props.dateFormat || extractDateFormat(format.value)
|
||||
return (
|
||||
props.dateFormat ||
|
||||
extractDateFormat(format.value || '') ||
|
||||
DEFAULT_FORMATS_DATE
|
||||
)
|
||||
})
|
||||
|
||||
const isValidValue = (date: [Dayjs, Dayjs]) => {
|
||||
@@ -882,7 +894,7 @@ const formatToString = (value: Dayjs | Dayjs[]) => {
|
||||
const parseUserInput = (value: Dayjs | Dayjs[]) => {
|
||||
return correctlyParseUserInput(
|
||||
value,
|
||||
format.value,
|
||||
format.value || '',
|
||||
lang.value,
|
||||
isDefaultFormat
|
||||
)
|
||||
|
||||
@@ -148,7 +148,8 @@ const unit = 'year'
|
||||
const { lang } = useLocale()
|
||||
const pickerBase = inject(PICKER_BASE_INJECTION_KEY) as any
|
||||
const isDefaultFormat = inject(
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY,
|
||||
undefined
|
||||
) as any
|
||||
const { shortcuts, disabledDate } = pickerBase.props
|
||||
const format = toRef(pickerBase.props, 'format')
|
||||
|
||||
@@ -133,7 +133,8 @@ const { lang } = useLocale()
|
||||
const leftDate = ref(dayjs().locale(lang.value))
|
||||
const rightDate = ref(dayjs().locale(lang.value).add(step, unit))
|
||||
const isDefaultFormat = inject(
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY,
|
||||
undefined
|
||||
) as any
|
||||
const pickerBase = inject(PICKER_BASE_INJECTION_KEY) as any
|
||||
const { shortcuts, disabledDate } = pickerBase.props
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
inject,
|
||||
provide,
|
||||
reactive,
|
||||
toRefs,
|
||||
} from 'vue'
|
||||
import { defineComponent, inject, provide, reactive, toRefs } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat.js'
|
||||
import advancedFormat from 'dayjs/plugin/advancedFormat.js'
|
||||
@@ -16,8 +9,6 @@ import dayOfYear from 'dayjs/plugin/dayOfYear.js'
|
||||
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter.js'
|
||||
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore.js'
|
||||
import {
|
||||
DEFAULT_FORMATS_DATE,
|
||||
DEFAULT_FORMATS_DATEPICKER,
|
||||
PICKER_BASE_INJECTION_KEY,
|
||||
ROOT_COMMON_PICKER_INJECTION_KEY,
|
||||
} from '@element-plus/components/time-picker'
|
||||
@@ -25,10 +16,7 @@ import { useNamespace } from '@element-plus/hooks'
|
||||
import { isUndefined } from '@element-plus/utils'
|
||||
import { UPDATE_MODEL_EVENT } from '@element-plus/constants'
|
||||
import { datePickerPanelProps } from './props/date-picker-panel'
|
||||
import {
|
||||
ROOT_PICKER_INJECTION_KEY,
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY,
|
||||
} from './constants'
|
||||
import { ROOT_PICKER_INJECTION_KEY } from './constants'
|
||||
import { getPanel } from './panel-utils'
|
||||
import { useCommonPicker } from '../../time-picker/src/composables/use-common-picker'
|
||||
|
||||
@@ -54,27 +42,10 @@ export default defineComponent({
|
||||
],
|
||||
setup(props, { slots, emit }) {
|
||||
const ns = useNamespace('picker-panel')
|
||||
const format = computed(
|
||||
() =>
|
||||
props.format ??
|
||||
(DEFAULT_FORMATS_DATEPICKER[props.type] || DEFAULT_FORMATS_DATE)
|
||||
)
|
||||
|
||||
const defaultFormatInjection = inject(
|
||||
ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY,
|
||||
undefined
|
||||
)
|
||||
if (isUndefined(defaultFormatInjection)) {
|
||||
const isDefaultFormat = computed(() => {
|
||||
return !props.format
|
||||
})
|
||||
provide(ROOT_PICKER_IS_DEFAULT_FORMAT_INJECTION_KEY, isDefaultFormat)
|
||||
}
|
||||
const pickerInjection = inject(PICKER_BASE_INJECTION_KEY, undefined)
|
||||
if (isUndefined(pickerInjection)) {
|
||||
const _props = reactive({
|
||||
...toRefs(props),
|
||||
format,
|
||||
})
|
||||
provide(PICKER_BASE_INJECTION_KEY, {
|
||||
props: _props,
|
||||
@@ -102,7 +73,6 @@ export default defineComponent({
|
||||
return (
|
||||
<Component
|
||||
{...props}
|
||||
format={format.value}
|
||||
parsedValue={parsedValue.value}
|
||||
onSet-picker-option={onSetPickerOption}
|
||||
onCalendar-change={onCalendarChange}
|
||||
|
||||
@@ -9,20 +9,16 @@ import type {
|
||||
import type { DatePickerType } from '../types'
|
||||
|
||||
export const datePickerPanelProps = buildProps({
|
||||
/**
|
||||
* @description format of the displayed value in the input box (in datetime/datetimerange mode)
|
||||
*/
|
||||
format: String,
|
||||
/**
|
||||
* @description optional, format of binding value. If not specified, the binding value will be a Date object
|
||||
*/
|
||||
valueFormat: String,
|
||||
/**
|
||||
* @description optional, format of the date displayed value in TimePicker's dropdown
|
||||
* @description optional, format of the date displayed in input's inner panel
|
||||
*/
|
||||
dateFormat: String,
|
||||
/**
|
||||
* @description optional, format of the time displayed value in TimePicker's dropdown
|
||||
* @description optional, format of the time displayed in input's inner panel
|
||||
*/
|
||||
timeFormat: String,
|
||||
/**
|
||||
|
||||
@@ -208,7 +208,7 @@ export const correctlyParseUserInput = (
|
||||
value: string | Dayjs | Dayjs[],
|
||||
format: string,
|
||||
lang: string,
|
||||
defaultFormat: ComputedRef<boolean>
|
||||
defaultFormat: ComputedRef<boolean> | undefined
|
||||
): Dayjs | Dayjs[] => {
|
||||
if (isArray(value)) {
|
||||
return value.map(
|
||||
@@ -216,7 +216,9 @@ export const correctlyParseUserInput = (
|
||||
)
|
||||
}
|
||||
if (isString(value)) {
|
||||
const dayjsValue = defaultFormat.value ? dayjs(value) : dayjs(value, format)
|
||||
const dayjsValue = defaultFormat?.value
|
||||
? dayjs(value)
|
||||
: dayjs(value, format)
|
||||
if (!dayjsValue.isValid()) {
|
||||
// return directly if not valid
|
||||
return dayjsValue
|
||||
|
||||
@@ -131,6 +131,35 @@ describe('Datetime Picker', () => {
|
||||
expect(dayjs(value.value).diff(dayjs()) < 10).toBeTruthy()
|
||||
})
|
||||
|
||||
it("should date input respect the default format 'YYYY-MM-DD' when format with only time format is setted", async () => {
|
||||
const modelValue = new Date(2000, 10, 10, 10, 10)
|
||||
const wrapper = mount(() => (
|
||||
<DatePicker v-model={modelValue} format="HH:mm:ss" type="datetime" />
|
||||
))
|
||||
|
||||
const input = wrapper.find('input')
|
||||
await input.trigger('blur')
|
||||
await input.trigger('focus')
|
||||
const timeInput = document.querySelector(
|
||||
'.el-date-picker__editor-wrap input'
|
||||
)
|
||||
expect((timeInput as HTMLInputElement).value).toBe('2000-11-10')
|
||||
})
|
||||
|
||||
it("should time input respect the default format 'HH:mm:ss' when format with only date format is setted", async () => {
|
||||
const modelValue = new Date(2000, 10, 10, 10, 10)
|
||||
const wrapper = mount(() => (
|
||||
<DatePicker v-model={modelValue} format="YYYY" type="datetime" />
|
||||
))
|
||||
const input = wrapper.find('input')
|
||||
await input.trigger('blur')
|
||||
await input.trigger('focus')
|
||||
const timeInput = document.querySelectorAll(
|
||||
'.el-date-picker__editor-wrap input'
|
||||
)[1]
|
||||
expect((timeInput as HTMLInputElement).value).toBe('10:10:00')
|
||||
})
|
||||
|
||||
it('time-picker select && input time && input date', async () => {
|
||||
const value = ref('')
|
||||
const wrapper = _mount(() => (
|
||||
@@ -1122,4 +1151,37 @@ describe('Datetimerange', () => {
|
||||
await input.trigger('focus')
|
||||
expect(wrapper.findComponent(CircleClose).exists()).toBe(true)
|
||||
})
|
||||
it("should date input respect the default format 'YYYY-MM-DD' when format with only time format is setted", async () => {
|
||||
const modelValue = [
|
||||
new Date(2000, 10, 10, 10, 10),
|
||||
new Date(2000, 10, 11, 10, 10),
|
||||
]
|
||||
const wrapper = mount(() => (
|
||||
<DatePicker v-model={modelValue} format="HH:mm:ss" type="datetimerange" />
|
||||
))
|
||||
const input = wrapper.find('input')
|
||||
await input.trigger('blur')
|
||||
await input.trigger('focus')
|
||||
const timeInput = document.querySelector(
|
||||
'.el-date-range-picker__editors-wrap input'
|
||||
)
|
||||
expect((timeInput as HTMLInputElement).value).toBe('2000-11-10')
|
||||
})
|
||||
|
||||
it("should time input respect the default format 'HH:mm:ss' when format with only date format is setted", async () => {
|
||||
const modelValue = [
|
||||
new Date(2000, 10, 10, 10, 10),
|
||||
new Date(2000, 10, 11, 10, 10),
|
||||
]
|
||||
const wrapper = mount(() => (
|
||||
<DatePicker v-model={modelValue} format="YYYY" type="datetimerange" />
|
||||
))
|
||||
const input = wrapper.find('input')
|
||||
await input.trigger('blur')
|
||||
await input.trigger('focus')
|
||||
const timeInput = document.querySelectorAll(
|
||||
'.el-date-range-picker__editors-wrap input'
|
||||
)[1]
|
||||
expect((timeInput as HTMLInputElement).value).toBe('10:10:00')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -63,11 +63,11 @@ export const timePickerDefaultProps = buildProps({
|
||||
*/
|
||||
valueFormat: String,
|
||||
/**
|
||||
* @description optional, format of the date displayed value in TimePicker's dropdown
|
||||
* @description optional, format of the date displayed in input's inner panel
|
||||
*/
|
||||
dateFormat: String,
|
||||
/**
|
||||
* @description optional, format of the time displayed value in TimePicker's dropdown
|
||||
* @description optional, format of the time displayed in input's inner panel
|
||||
*/
|
||||
timeFormat: String,
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user