mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-04 20:27:44 +08:00
refactor(components): [time-picker] time-picker (#8160)
* refactor(components): [time-picker] time-picker * Refactor `time-picker` to tsx. * chore: refactor to script setup * chore: fix typing issue in `picker` * chore: fix API exposing Co-authored-by: JeremyWuuuuu <15975785+JeremyWuuuuu@users.noreply.github.com>
This commit is contained in:
parent
6b6c5a4a87
commit
5b233da008
@ -49,7 +49,6 @@ export default defineComponent({
|
||||
|
||||
const commonPicker = ref<InstanceType<typeof CommonPicker>>()
|
||||
const refProps = {
|
||||
...props,
|
||||
focus: (focusStartInput = true) => {
|
||||
commonPicker.value?.focus(focusStartInput)
|
||||
},
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,28 +1,32 @@
|
||||
import { isValidComponentSize } from '@element-plus/utils'
|
||||
import { buildProps, definePropType } from '@element-plus/utils'
|
||||
import { useSizeProp } from '@element-plus/hooks'
|
||||
import { CircleClose } from '@element-plus/icons-vue'
|
||||
|
||||
import type { Component, PropType } from 'vue'
|
||||
import type { Component, ExtractPropTypes } from 'vue'
|
||||
import type { Options } from '@popperjs/core'
|
||||
import type { ComponentSize } from '@element-plus/constants'
|
||||
import type { Dayjs } from 'dayjs'
|
||||
|
||||
export const timePickerDefaultProps = {
|
||||
export type SingleOrRange<T> = T | [T, T]
|
||||
export type DateModelType = number | string | Date
|
||||
export type ModelValueType = SingleOrRange<DateModelType>
|
||||
export type DayOrDays = SingleOrRange<Dayjs>
|
||||
export type DateOrDates = SingleOrRange<Date>
|
||||
export type UserInput = SingleOrRange<string | null>
|
||||
|
||||
export const timePickerDefaultProps = buildProps({
|
||||
id: {
|
||||
type: [Array, String],
|
||||
type: definePropType<SingleOrRange<string>>([Array, String]),
|
||||
},
|
||||
name: {
|
||||
type: [Array, String],
|
||||
type: definePropType<SingleOrRange<string>>([Array, String]),
|
||||
default: '',
|
||||
},
|
||||
popperClass: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
format: {
|
||||
type: String,
|
||||
},
|
||||
valueFormat: {
|
||||
type: String as PropType<string>,
|
||||
},
|
||||
format: String,
|
||||
valueFormat: String,
|
||||
type: {
|
||||
type: String,
|
||||
default: '',
|
||||
@ -32,7 +36,7 @@ export const timePickerDefaultProps = {
|
||||
default: true,
|
||||
},
|
||||
clearIcon: {
|
||||
type: [String, Object] as PropType<string | Component>,
|
||||
type: definePropType<string | Component>([String, Object]),
|
||||
default: CircleClose,
|
||||
},
|
||||
editable: {
|
||||
@ -40,13 +44,10 @@ export const timePickerDefaultProps = {
|
||||
default: true,
|
||||
},
|
||||
prefixIcon: {
|
||||
type: [String, Object] as PropType<string | Component>,
|
||||
type: definePropType<string | Component>([String, Object]),
|
||||
default: '',
|
||||
},
|
||||
size: {
|
||||
type: String as PropType<ComponentSize>,
|
||||
validator: isValidComponentSize,
|
||||
},
|
||||
size: useSizeProp,
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@ -60,13 +61,11 @@ export const timePickerDefaultProps = {
|
||||
default: '',
|
||||
},
|
||||
popperOptions: {
|
||||
type: Object as PropType<Partial<Options>>,
|
||||
type: definePropType<Partial<Options>>(Object),
|
||||
default: () => ({}),
|
||||
},
|
||||
modelValue: {
|
||||
type: [Date, Array, String, Number] as PropType<
|
||||
number | string | Date | (number | string | Date)[]
|
||||
>,
|
||||
type: definePropType<ModelValueType>([Date, Array, String, Number]),
|
||||
default: '',
|
||||
},
|
||||
rangeSeparator: {
|
||||
@ -76,10 +75,10 @@ export const timePickerDefaultProps = {
|
||||
startPlaceholder: String,
|
||||
endPlaceholder: String,
|
||||
defaultValue: {
|
||||
type: [Date, Array] as PropType<Date | Date[]>,
|
||||
type: definePropType<SingleOrRange<Date>>([Date, Array]),
|
||||
},
|
||||
defaultTime: {
|
||||
type: [Date, Array] as PropType<Date | Date[]>,
|
||||
type: definePropType<SingleOrRange<Date>>([Date, Array]),
|
||||
},
|
||||
isRange: {
|
||||
type: Boolean,
|
||||
@ -113,7 +112,7 @@ export const timePickerDefaultProps = {
|
||||
default: undefined,
|
||||
},
|
||||
tabindex: {
|
||||
type: [String, Number],
|
||||
type: definePropType<string | number>([String, Number]),
|
||||
default: 0,
|
||||
},
|
||||
validateEvent: {
|
||||
@ -121,4 +120,20 @@ export const timePickerDefaultProps = {
|
||||
default: true,
|
||||
},
|
||||
unlinkPanels: Boolean,
|
||||
} as const)
|
||||
|
||||
export type TimePickerDefaultProps = ExtractPropTypes<
|
||||
typeof timePickerDefaultProps
|
||||
>
|
||||
|
||||
export interface PickerOptions {
|
||||
isValidValue: (date: DayOrDays) => boolean
|
||||
handleKeydownInput: (event: KeyboardEvent) => void
|
||||
parseUserInput: (value: UserInput) => DayOrDays
|
||||
formatToString: (value: DayOrDays) => UserInput
|
||||
getRangeAvailableTime: (date: DayOrDays) => DayOrDays
|
||||
getDefaultValue: () => DayOrDays
|
||||
panelReady: boolean
|
||||
handleClear: () => void
|
||||
handleFocusPicker?: () => void
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ const getRangeAvailableTime = ([start, end]: Array<Dayjs>) => {
|
||||
return [
|
||||
getAvailableTime(start, 'start', true, end),
|
||||
getAvailableTime(end, 'end', false, start),
|
||||
]
|
||||
] as const
|
||||
}
|
||||
|
||||
const { getAvailableHours, getAvailableMinutes, getAvailableSeconds } =
|
||||
|
@ -1,55 +0,0 @@
|
||||
import { defineComponent, h, provide, ref } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat.js'
|
||||
import { DEFAULT_FORMATS_TIME } from './common/constant'
|
||||
import Picker from './common/picker.vue'
|
||||
import TimePickPanel from './time-picker-com/panel-time-pick.vue'
|
||||
import TimeRangePanel from './time-picker-com/panel-time-range.vue'
|
||||
import { timePickerDefaultProps } from './common/props'
|
||||
dayjs.extend(customParseFormat)
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ElTimePicker',
|
||||
install: null,
|
||||
props: {
|
||||
...timePickerDefaultProps,
|
||||
isRange: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
setup(props, ctx) {
|
||||
const commonPicker = ref(null)
|
||||
const type = props.isRange ? 'timerange' : 'time'
|
||||
const panel = props.isRange ? TimeRangePanel : TimePickPanel
|
||||
const refProps = {
|
||||
...props,
|
||||
focus: () => {
|
||||
commonPicker.value?.handleFocusInput()
|
||||
},
|
||||
blur: () => {
|
||||
commonPicker.value?.handleBlurInput()
|
||||
},
|
||||
}
|
||||
provide('ElPopperOptions', props.popperOptions)
|
||||
ctx.expose(refProps)
|
||||
return () => {
|
||||
const format = props.format ?? DEFAULT_FORMATS_TIME
|
||||
return h(
|
||||
Picker,
|
||||
{
|
||||
...props, // allow format to be overwrite
|
||||
format,
|
||||
type,
|
||||
ref: commonPicker,
|
||||
'onUpdate:modelValue': (value) =>
|
||||
ctx.emit('update:modelValue', value),
|
||||
},
|
||||
{
|
||||
default: (scopedProps) => h(panel, scopedProps),
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
63
packages/components/time-picker/src/time-picker.tsx
Normal file
63
packages/components/time-picker/src/time-picker.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
import { defineComponent, provide, ref } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat.js'
|
||||
import { DEFAULT_FORMATS_TIME } from './common/constant'
|
||||
import Picker from './common/picker.vue'
|
||||
import TimePickPanel from './time-picker-com/panel-time-pick.vue'
|
||||
import TimeRangePanel from './time-picker-com/panel-time-range.vue'
|
||||
import { timePickerDefaultProps } from './common/props'
|
||||
dayjs.extend(customParseFormat)
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ElTimePicker',
|
||||
install: null,
|
||||
props: {
|
||||
...timePickerDefaultProps,
|
||||
isRange: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
setup(props, ctx) {
|
||||
const commonPicker = ref<InstanceType<typeof Picker>>()
|
||||
const [type, Panel] = props.isRange
|
||||
? ['timerange', TimeRangePanel]
|
||||
: ['time', TimePickPanel]
|
||||
|
||||
const modelUpdater = (value: any) => ctx.emit('update:modelValue', value)
|
||||
provide('ElPopperOptions', props.popperOptions)
|
||||
ctx.expose({
|
||||
/**
|
||||
* @description focus on the input element
|
||||
*/
|
||||
focus: (e: FocusEvent | undefined) => {
|
||||
commonPicker.value?.handleFocusInput(e)
|
||||
},
|
||||
/**
|
||||
* @description blur from the input element
|
||||
*/
|
||||
blur: (e: FocusEvent | undefined) => {
|
||||
commonPicker.value?.handleBlurInput(e)
|
||||
},
|
||||
})
|
||||
|
||||
return () => {
|
||||
const format = props.format ?? DEFAULT_FORMATS_TIME
|
||||
|
||||
return (
|
||||
<Picker
|
||||
{...props}
|
||||
ref={commonPicker}
|
||||
type={type}
|
||||
format={format}
|
||||
onUpdate:modelValue={modelUpdater}
|
||||
>
|
||||
{{
|
||||
default: (props: any) => <Panel {...props} />,
|
||||
}}
|
||||
</Picker>
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
Loading…
Reference in New Issue
Block a user