mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-02-11 13:10:26 +08:00
feat(date-picker): type
prop supports 'quarterrange'
and 'yearrange'
This commit is contained in:
parent
53f86e7c39
commit
3ed7118ca0
@ -10,6 +10,12 @@
|
||||
- Fix `n-select` will remove select value in multiple mode in `form` if Enter key is pressed in input element. Closes [#3169](https://github.com/TuSimple/naive-ui/issues/3169).
|
||||
- Fix `n-select`'s filter prop not working, closes [#3175](https://github.com/TuSimple/naive-ui/issues/3175).
|
||||
|
||||
### Feats
|
||||
|
||||
### Feats
|
||||
|
||||
- `n-date-picker`'s `type` prop supports `'quarterrange'` and `'yearrange'`.
|
||||
|
||||
## 2.30.6
|
||||
|
||||
### Fixes
|
||||
|
@ -10,6 +10,10 @@
|
||||
- 修复 `n-select` 在 `form` 中,多选的情况下,在 input 元素中按下 Enter 键会导致选项被清除,关闭 [#3169](https://github.com/TuSimple/naive-ui/issues/3169)
|
||||
- 修复 `n-select` 的 `filter` 属性不生效,关闭 [#3175](https://github.com/TuSimple/naive-ui/issues/3175)
|
||||
|
||||
### Feats
|
||||
|
||||
- `n-date-picker` `type` 属性支持 `'quarterrange'` 和 `'yearrange'`
|
||||
|
||||
## 2.30.6
|
||||
|
||||
### Fixes
|
||||
|
@ -13,7 +13,9 @@ datetimerange.vue
|
||||
month.vue
|
||||
monthrange.vue
|
||||
year.vue
|
||||
yearrange.vue
|
||||
quarter.vue
|
||||
quarterrange.vue
|
||||
size.vue
|
||||
default-time.vue
|
||||
disabled.vue
|
||||
@ -134,7 +136,7 @@ panel.vue
|
||||
| on-update:formatted-value | `(value: string \| null, timestampValue: number \| null) => void` | `undefined` | Formatted value changed callback. | 2.24.0 |
|
||||
| on-update:value | `(value: number \| null, formattedValue: string \| null) => void` | `undefined` | Value changed callback. | `formattedValue` 2.24.0 |
|
||||
|
||||
### MonthRange Type Props
|
||||
### MonthRange, QuarterRange, YearRange Type Props
|
||||
|
||||
| Name | Type | Default | Description | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
|
20
src/date-picker/demos/enUS/quarterrange.demo.vue
Normal file
20
src/date-picker/demos/enUS/quarterrange.demo.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<markdown>
|
||||
# 季度范围
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-date-picker v-model:value="timestamp" type="quarterrange" clearable />
|
||||
<pre>{{ JSON.stringify(timestamp) }}</pre>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
timestamp: ref<[number, number]>([1183135260000, Date.now()])
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
20
src/date-picker/demos/enUS/yearrange.demo.vue
Normal file
20
src/date-picker/demos/enUS/yearrange.demo.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<markdown>
|
||||
# 年份范围
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-date-picker v-model:value="timestamp" type="yearrange" clearable />
|
||||
<pre>{{ JSON.stringify(timestamp) }}</pre>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
timestamp: ref<[number, number]>([1183135260000, Date.now()])
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -13,7 +13,9 @@ datetimerange.vue
|
||||
month.vue
|
||||
monthrange.vue
|
||||
year.vue
|
||||
yearrange.vue
|
||||
quarter.vue
|
||||
quarterrange.vue
|
||||
size.vue
|
||||
default-time.vue
|
||||
disabled.vue
|
||||
@ -133,7 +135,7 @@ panel-debug.vue
|
||||
| on-update:formatted-value | `(value: string \| null, timestampValue: number \| null) => void` | `undefined` | 可控数据更新时触发的回调函数 | 2.24.0 |
|
||||
| on-update:value | `(value: number \| null, formattedValue: string \| null) => void` | `undefined` | 可控数据更新时触发的回调函数 | `formattedValue` 2.24.0 |
|
||||
|
||||
### MonthRange 类型的 Props
|
||||
### MonthRange、QuarterRange、YearRange 类型的 Props
|
||||
|
||||
| 名称 | 类型 | 默认值 | 说明 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
|
20
src/date-picker/demos/zhCN/quarterrange.demo.vue
Normal file
20
src/date-picker/demos/zhCN/quarterrange.demo.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<markdown>
|
||||
# 季度范围
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-date-picker v-model:value="timestamp" type="quarterrange" clearable />
|
||||
<pre>{{ JSON.stringify(timestamp) }}</pre>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
timestamp: ref<[number, number]>([1183135260000, Date.now()])
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
20
src/date-picker/demos/zhCN/yearrange.demo.vue
Normal file
20
src/date-picker/demos/zhCN/yearrange.demo.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<markdown>
|
||||
# 年份范围
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-date-picker v-model:value="timestamp" type="yearrange" clearable />
|
||||
<pre>{{ JSON.stringify(timestamp) }}</pre>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
timestamp: ref<[number, number]>([1183135260000, Date.now()])
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -206,11 +206,13 @@ export default defineComponent({
|
||||
case 'datetimerange':
|
||||
return localeRef.value.dateTimeFormat
|
||||
case 'year':
|
||||
case 'yearrange':
|
||||
return localeRef.value.yearTypeFormat
|
||||
case 'month':
|
||||
case 'monthrange':
|
||||
return localeRef.value.monthTypeFormat
|
||||
case 'quarter':
|
||||
case 'quarterrange':
|
||||
return localeRef.value.quarterFormat
|
||||
}
|
||||
})
|
||||
@ -287,7 +289,13 @@ export default defineComponent({
|
||||
)
|
||||
})
|
||||
const isRangeRef = computed(() => {
|
||||
return ['daterange', 'datetimerange', 'monthrange'].includes(props.type)
|
||||
return [
|
||||
'daterange',
|
||||
'datetimerange',
|
||||
'monthrange',
|
||||
'quarterrange',
|
||||
'yearrange'
|
||||
].includes(props.type)
|
||||
})
|
||||
const localizedPlacehoderRef = computed(() => {
|
||||
const { placeholder } = props
|
||||
@ -978,11 +986,13 @@ export default defineComponent({
|
||||
/>
|
||||
) : type === 'month' || type === 'year' || type === 'quarter' ? (
|
||||
<MonthPanel {...commonPanelProps} type={type} key={type} />
|
||||
) : type === 'monthrange' ? (
|
||||
) : type === 'monthrange' ||
|
||||
type === 'yearrange' ||
|
||||
type === 'quarterrange' ? (
|
||||
<MonthRangePanel {...commonPanelProps} type={type} />
|
||||
) : (
|
||||
) : (
|
||||
<DatePanel {...commonPanelProps} />
|
||||
)
|
||||
)
|
||||
}
|
||||
if (this.panel) {
|
||||
return renderPanel()
|
||||
|
@ -11,3 +11,5 @@ export type DatePickerType =
|
||||
| 'year'
|
||||
| 'quarter'
|
||||
| 'monthrange'
|
||||
| 'quarterrange'
|
||||
| 'yearrange'
|
||||
|
@ -11,7 +11,7 @@ import { VirtualList } from 'vueuc'
|
||||
import { NxButton } from '../../../button'
|
||||
import { NBaseFocusDetector, NScrollbar } from '../../../_internal'
|
||||
import { warnOnce } from '../../../_utils'
|
||||
import type { MonthItem, YearItem } from '../utils'
|
||||
import type { MonthItem, QuarterItem, YearItem } from '../utils'
|
||||
import { MONTH_ITEM_HEIGHT } from '../config'
|
||||
import { useDualCalendar, useDualCalendarProps } from './use-dual-calendar'
|
||||
|
||||
@ -20,7 +20,7 @@ export default defineComponent({
|
||||
props: {
|
||||
...useDualCalendarProps,
|
||||
type: {
|
||||
type: String as PropType<'monthrange'>,
|
||||
type: String as PropType<'monthrange' | 'yearrange' | 'quarterrange'>,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
@ -39,7 +39,7 @@ export default defineComponent({
|
||||
}
|
||||
const useCalendarRef = useDualCalendar(props, props.type)
|
||||
const renderItem = (
|
||||
item: YearItem | MonthItem,
|
||||
item: YearItem | MonthItem | QuarterItem,
|
||||
i: number,
|
||||
mergedClsPrefix: string,
|
||||
type: 'start' | 'end'
|
||||
@ -72,7 +72,9 @@ export default defineComponent({
|
||||
>
|
||||
{item.type === 'month'
|
||||
? item.dateObject.month + 1
|
||||
: item.dateObject.year}
|
||||
: item.type === 'quarter'
|
||||
? item.dateObject.quarter
|
||||
: item.dateObject.year}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -137,7 +139,7 @@ export default defineComponent({
|
||||
)
|
||||
}}
|
||||
</NScrollbar>
|
||||
{type === 'monthrange' ? (
|
||||
{type === 'monthrange' || type === 'quarterrange' ? (
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__picker-col`}
|
||||
>
|
||||
@ -148,12 +150,17 @@ export default defineComponent({
|
||||
>
|
||||
{{
|
||||
default: () => [
|
||||
this.startMonthArray.map((monthItem, i) =>
|
||||
renderItem(monthItem, i, mergedClsPrefix, 'start')
|
||||
(type === 'monthrange'
|
||||
? this.startMonthArray
|
||||
: this.startQuarterArray
|
||||
).map((item, i) =>
|
||||
renderItem(item, i, mergedClsPrefix, 'start')
|
||||
),
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__padding`}
|
||||
/>
|
||||
type === 'monthrange' && (
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__padding`}
|
||||
/>
|
||||
)
|
||||
]
|
||||
}}
|
||||
</NScrollbar>
|
||||
@ -203,7 +210,7 @@ export default defineComponent({
|
||||
)
|
||||
}}
|
||||
</NScrollbar>
|
||||
{type === 'monthrange' ? (
|
||||
{type === 'monthrange' || type === 'quarterrange' ? (
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__picker-col`}
|
||||
>
|
||||
@ -214,12 +221,17 @@ export default defineComponent({
|
||||
>
|
||||
{{
|
||||
default: () => [
|
||||
this.endMonthArray.map((monthItem, i) =>
|
||||
renderItem(monthItem, i, mergedClsPrefix, 'end')
|
||||
(type === 'monthrange'
|
||||
? this.endMonthArray
|
||||
: this.endQuarterArray
|
||||
).map((item, i) =>
|
||||
renderItem(item, i, mergedClsPrefix, 'end')
|
||||
),
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__padding`}
|
||||
/>
|
||||
type === 'monthrange' && (
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__padding`}
|
||||
/>
|
||||
)
|
||||
]
|
||||
}}
|
||||
</NScrollbar>
|
||||
|
@ -10,7 +10,8 @@ import {
|
||||
startOfDay,
|
||||
set,
|
||||
getDate,
|
||||
getTime
|
||||
getTime,
|
||||
startOfQuarter
|
||||
} from 'date-fns/esm'
|
||||
import { VirtualListInst } from 'vueuc'
|
||||
import {
|
||||
@ -22,7 +23,9 @@ import {
|
||||
yearArray,
|
||||
monthArray,
|
||||
getDefaultTime,
|
||||
pluckValueFromRange
|
||||
pluckValueFromRange,
|
||||
QuarterItem,
|
||||
quarterArray
|
||||
} from '../utils'
|
||||
import { usePanelCommon, usePanelCommonProps } from './use-panel-common'
|
||||
import {
|
||||
@ -47,7 +50,12 @@ const useDualCalendarProps = {
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
function useDualCalendar (
|
||||
props: ExtractPropTypes<typeof useDualCalendarProps>,
|
||||
type: 'daterange' | 'datetimerange' | 'monthrange'
|
||||
type:
|
||||
| 'daterange'
|
||||
| 'datetimerange'
|
||||
| 'monthrange'
|
||||
| 'quarterrange'
|
||||
| 'yearrange'
|
||||
) {
|
||||
const {
|
||||
isDateDisabledRef,
|
||||
@ -217,6 +225,14 @@ function useDualCalendar (
|
||||
const endYearArrayRef = computed(() => {
|
||||
return yearArray(pluckValueFromRange(props.value, 'end'), nowRef.value)
|
||||
})
|
||||
const startQuarterArrayRef = computed(() => {
|
||||
const startValue = pluckValueFromRange(props.value, 'start')
|
||||
return quarterArray(startValue ?? Date.now(), startValue, nowRef.value)
|
||||
})
|
||||
const endQuarterArrayRef = computed(() => {
|
||||
const endValue = pluckValueFromRange(props.value, 'end')
|
||||
return quarterArray(endValue ?? Date.now(), endValue, nowRef.value)
|
||||
})
|
||||
const startMonthArrayRef = computed(() => {
|
||||
const startValue = pluckValueFromRange(props.value, 'start')
|
||||
return monthArray(startValue ?? Date.now(), startValue, nowRef.value)
|
||||
@ -711,17 +727,27 @@ function useDualCalendar (
|
||||
}
|
||||
// only for monthrange
|
||||
function handleColItemClick (
|
||||
dateItem: MonthItem | YearItem,
|
||||
dateItem: MonthItem | QuarterItem | YearItem,
|
||||
clickType: 'start' | 'end'
|
||||
): void {
|
||||
const { value } = props
|
||||
const noCurrentValue = !Array.isArray(value)
|
||||
const itemTs =
|
||||
dateItem.type === 'year'
|
||||
dateItem.type === 'year' && type !== 'yearrange'
|
||||
? noCurrentValue
|
||||
? set(dateItem.ts, { month: getMonth(new Date()) }).valueOf()
|
||||
? set(dateItem.ts, {
|
||||
month: getMonth(
|
||||
type === 'quarterrange'
|
||||
? startOfQuarter(new Date())
|
||||
: new Date()
|
||||
)
|
||||
}).valueOf()
|
||||
: set(dateItem.ts, {
|
||||
month: getMonth(value[clickType === 'start' ? 0 : 1])
|
||||
month: getMonth(
|
||||
type === 'quarterrange'
|
||||
? startOfQuarter(value[clickType === 'start' ? 0 : 1])
|
||||
: value[clickType === 'start' ? 0 : 1]
|
||||
)
|
||||
}).valueOf()
|
||||
: dateItem.ts
|
||||
if (noCurrentValue) {
|
||||
@ -750,6 +776,7 @@ function useDualCalendar (
|
||||
panelCommon.doUpdateValue(nextValue, props.panel)
|
||||
switch (type) {
|
||||
case 'monthrange':
|
||||
case 'quarterrange':
|
||||
panelCommon.disableTransitionOneTick()
|
||||
if (otherPartsChanged) {
|
||||
justifyColumnsScrollState(nextValue, 'start')
|
||||
@ -758,6 +785,10 @@ function useDualCalendar (
|
||||
justifyColumnsScrollState(nextValue, clickType)
|
||||
}
|
||||
break
|
||||
case 'yearrange':
|
||||
panelCommon.disableTransitionOneTick()
|
||||
justifyColumnsScrollState(nextValue, 'start')
|
||||
justifyColumnsScrollState(nextValue, 'end')
|
||||
}
|
||||
}
|
||||
function handleStartYearVlScroll (): void {
|
||||
@ -816,8 +847,10 @@ function useDualCalendar (
|
||||
endDateArray: endDateArrayRef,
|
||||
startYearArray: startYearArrayRef,
|
||||
startMonthArray: startMonthArrayRef,
|
||||
startQuarterArray: startQuarterArrayRef,
|
||||
endYearArray: endYearArrayRef,
|
||||
endMonthArray: endMonthArrayRef,
|
||||
endQuarterArray: endQuarterArrayRef,
|
||||
isSelecting: isSelectingRef,
|
||||
handleRangeShortcutMouseenter,
|
||||
handleRangeShortcutClick,
|
||||
|
@ -267,12 +267,12 @@ function monthArray (
|
||||
}
|
||||
|
||||
function quarterArray (
|
||||
quarterTs: number,
|
||||
yearAnchorTs: number,
|
||||
valueTs: number | null,
|
||||
currentTs: number
|
||||
): QuarterItem[] {
|
||||
const calendarQuarters: QuarterItem[] = []
|
||||
const yearStart = startOfYear(quarterTs)
|
||||
const yearStart = startOfYear(yearAnchorTs)
|
||||
for (let i = 0; i < 4; i++) {
|
||||
calendarQuarters.push(
|
||||
quarterItem(getTime(addQuarters(yearStart, i)), valueTs, currentTs)
|
||||
|
@ -21,6 +21,8 @@ export default {
|
||||
calendarLeftPaddingYear: '0',
|
||||
calendarLeftPaddingQuarter: '0',
|
||||
calendarLeftPaddingMonthrange: '0',
|
||||
calendarLeftPaddingQuarterrange: '0',
|
||||
calendarLeftPaddingYearrange: '0',
|
||||
calendarRightPaddingDate: '6px 12px 4px 12px',
|
||||
calendarRightPaddingDatetime: '4px 12px',
|
||||
calendarRightPaddingDaterange: '6px 12px 4px 12px',
|
||||
@ -28,5 +30,7 @@ export default {
|
||||
calendarRightPaddingMonth: '0',
|
||||
calendarRightPaddingYear: '0',
|
||||
calendarRightPaddingQuarter: '0',
|
||||
calendarRightPaddingMonthrange: '0'
|
||||
calendarRightPaddingMonthrange: '0',
|
||||
calendarRightPaddingQuarterrange: '0',
|
||||
calendarRightPaddingYearrange: '0'
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user