Skip to content

Commit

Permalink
feat(comp:date-picker): timeFormat is now infered from format by defa…
Browse files Browse the repository at this point in the history
…ult (#1045)

fix(comp:date-picker): time of Date value should be kept after range value selected
  • Loading branch information
sallerli1 committed Jul 28, 2022
1 parent 70a6d4a commit 0bb2f8e
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 23 deletions.
1 change: 1 addition & 0 deletions packages/components/date-picker/demo/Format.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<IxDatePicker v-model:value="value" type="month" format="MM/yyyy"></IxDatePicker>
<IxDatePicker v-model:value="value" type="quarter" format="'Q'Q/yyyy"></IxDatePicker>
<IxDatePicker v-model:value="value" type="year" format="yy"></IxDatePicker>
<IxDatePicker v-model:value="value" type="datetime" format="dd/MM/yyyy hh:mm"></IxDatePicker>
</IxSpace>
</template>

Expand Down
52 changes: 46 additions & 6 deletions packages/components/date-picker/src/composables/useFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import type { DatePickerProps, DateRangePickerProps } from '../types'
import type { ComputedRef } from 'vue'

import { computed } from 'vue'
import { type ComputedRef, computed } from 'vue'

import { type DatePickerConfig, useGlobalConfig } from '@idux/components/config'
import { type DatePickerConfig } from '@idux/components/config'

export interface FormatContext {
interface TimePanelEnabledStatus {
hourEnabled: ComputedRef<boolean>
hourUse12Hours: ComputedRef<boolean>
minuteEnabled: ComputedRef<boolean>
secondEnabled: ComputedRef<boolean>
use12Hours: ComputedRef<boolean>
}

export interface FormatContext extends Omit<TimePanelEnabledStatus, 'hourUse12Hours'> {
formatRef: ComputedRef<string>
dateFormatRef: ComputedRef<string>
timeFormatRef: ComputedRef<string>
Expand All @@ -30,12 +37,16 @@ const defaultFormat = {
} as const

export function useFormat(props: DatePickerProps | DateRangePickerProps, config: DatePickerConfig): FormatContext {
const timePickerConfig = useGlobalConfig('timePicker')
const formatRef = computed(() => {
const type = props.type
return props.format ?? config.format?.[type] ?? defaultFormat[type]
})

const { hourEnabled, hourUse12Hours, minuteEnabled, secondEnabled, use12Hours } = useTimePanelEnabledStatus(
props,
formatRef,
)

const dateFormatRef = computed(() => {
if (props.type !== 'datetime') {
return formatRef.value
Expand All @@ -45,12 +56,41 @@ export function useFormat(props: DatePickerProps | DateRangePickerProps, config:
})

const timeFormatRef = computed(() => {
return props.timeFormat ?? timePickerConfig.format
if (props.timeFormat) {
return props.timeFormat
}

const hourFormat = hourEnabled.value && (hourUse12Hours.value ? 'hh' : 'HH')
const timeFormatBase = [hourFormat, minuteEnabled.value && 'mm', secondEnabled.value && 'ss']
.filter(Boolean)
.join(':')

return use12Hours.value ? `${timeFormatBase} a` : timeFormatBase
})

return {
formatRef,
dateFormatRef,
timeFormatRef,

hourEnabled,
minuteEnabled,
secondEnabled,
use12Hours,
}
}

function useTimePanelEnabledStatus(
props: DatePickerProps | DateRangePickerProps,
formatRef: ComputedRef<string>,
): TimePanelEnabledStatus {
const _formatRef = computed(() => props.timeFormat ?? formatRef.value)

return {
hourEnabled: computed(() => /[hH]/.test(_formatRef.value)),
hourUse12Hours: computed(() => /h/.test(_formatRef.value)),
minuteEnabled: computed(() => /m/.test(_formatRef.value)),
secondEnabled: computed(() => /s/.test(_formatRef.value)),
use12Hours: computed(() => /[aA]/.test(_formatRef.value)),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { type ComputedRef, computed, watch } from 'vue'

import { callEmit, convertArray, useState } from '@idux/cdk/utils'

import { sortRangeValue } from '../utils'
import { applyDateTime, sortRangeValue } from '../utils'

export interface RangePanelStateContext {
panelValue: ComputedRef<(Date | undefined)[] | undefined>
Expand Down Expand Up @@ -49,8 +49,16 @@ export function useRangePanelState(props: DateRangePanelProps, dateConfig: DateC
setIsSelecting(true)
setSelectingDate([value, undefined])
} else {
const propsValue = convertArray(props.value)

setIsSelecting(false)
handleChange([selectingDate.value?.[0], value])
handleChange(
[selectingDate.value?.[0], value].map((dateValue, index) =>
propsValue[index]
? applyDateTime(dateConfig, propsValue[index], dateValue!, ['hour', 'minute', 'second'])
: dateValue,
),
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,48 @@ import { isArray } from 'lodash-es'

export function useTimePanelProps(
props: DatePickerProps,
timeFormatRef: ComputedRef<string>,
hourEnabled: ComputedRef<boolean>,
minuteEnabled: ComputedRef<boolean>,
secondEnabled: ComputedRef<boolean>,
use12Hours: ComputedRef<boolean>,
): ComputedRef<ɵTimePanelProps> {
return computed(() => getTimePanelProps(props.timePanelOptions ?? {}, timeFormatRef))
return computed(() => ({
...getTimePanelProps(props.timePanelOptions ?? {}),
hourEnabled: hourEnabled.value,
minuteEnabled: minuteEnabled.value,
secondEnabled: secondEnabled.value,
use12Hours: use12Hours.value,
}))
}

export function useRangeTimePanelProps(
props: DateRangePickerProps,
timeFormatRef: ComputedRef<string>,
hourEnabled: ComputedRef<boolean>,
minuteEnabled: ComputedRef<boolean>,
secondEnabled: ComputedRef<boolean>,
use12Hours: ComputedRef<boolean>,
): ComputedRef<ɵTimePanelProps[]> {
const getOptions = (isFrom: boolean) =>
(isArray(props.timePanelOptions) ? props.timePanelOptions[isFrom ? 0 : 1] : props.timePanelOptions) ?? {}

const rangeTimePanelProps = computed(() => [
getTimePanelProps(getOptions(true), timeFormatRef),
getTimePanelProps(getOptions(false), timeFormatRef),
])
const rangeTimePanelProps = computed(() => {
const enabledStatus = {
hourEnabled: hourEnabled.value,
minuteEnabled: minuteEnabled.value,
secondEnabled: secondEnabled.value,
use12Hours: use12Hours.value,
}

return [
{ ...getTimePanelProps(getOptions(true)), ...enabledStatus },
{ ...getTimePanelProps(getOptions(false)), ...enabledStatus },
]
})

return rangeTimePanelProps
}

function getTimePanelProps(timePanelOptions: TimePanelOptions, timeFormatRef: ComputedRef<string>): ɵTimePanelProps {
function getTimePanelProps(timePanelOptions: TimePanelOptions): ɵTimePanelProps {
const { disabledHours, disabledMinutes, disabledSeconds, hideDisabledOptions, hourStep, minuteStep, secondStep } =
timePanelOptions

Expand All @@ -46,9 +67,5 @@ function getTimePanelProps(timePanelOptions: TimePanelOptions, timeFormatRef: Co
hourStep,
minuteStep,
secondStep,
hourEnabled: /[hH]/.test(timeFormatRef.value),
minuteEnabled: /m/.test(timeFormatRef.value),
secondEnabled: /s/.test(timeFormatRef.value),
use12Hours: /[aA]/.test(timeFormatRef.value),
}
}
8 changes: 6 additions & 2 deletions packages/components/date-picker/src/content/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export default defineComponent({
mergedPrefixCls,
dateFormatRef,
timeFormatRef,
hourEnabled,
minuteEnabled,
secondEnabled,
use12Hours,
slots,
inputEnableStatus,
inputRef,
Expand Down Expand Up @@ -79,7 +83,7 @@ export default defineComponent({
}
}

const _handleDateInputClear = (evt: Event) => {
const _handleDateInputClear = (evt: MouseEvent) => {
if (!inputEnableStatus.value.enableOverlayTimeInput) {
handleClear(evt)
}
Expand All @@ -88,7 +92,7 @@ export default defineComponent({
}

const inputProps = useInputProps(context)
const timePanelProps = useTimePanelProps(props, timeFormatRef)
const timePanelProps = useTimePanelProps(props, hourEnabled, minuteEnabled, secondEnabled, use12Hours)

const renderInputs = (prefixCls: string) => {
if (!inputEnableStatus.value.enableOverlayDateInput) {
Expand Down
6 changes: 5 additions & 1 deletion packages/components/date-picker/src/content/RangeContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export default defineComponent({
slots,
dateFormatRef,
timeFormatRef,
hourEnabled,
minuteEnabled,
secondEnabled,
use12Hours,
rangeControlContext: { buffer, visiblePanel, fromControl, toControl, handlePanelChange },
mergedPrefixCls,
inputEnableStatus,
Expand Down Expand Up @@ -56,7 +60,7 @@ export default defineComponent({
}

const inputProps = useInputProps(context)
const timePanelProps = useRangeTimePanelProps(props, timeFormatRef)
const timePanelProps = useRangeTimePanelProps(props, hourEnabled, minuteEnabled, secondEnabled, use12Hours)

const renderInputsSide = (prefixCls: string, isFrom: boolean) => {
const { enableOverlayTimeInput } = inputEnableStatus.value
Expand Down

0 comments on commit 0bb2f8e

Please sign in to comment.