2
0
mirror of https://github.com/tusen-ai/naive-ui.git synced 2025-04-24 15:01:22 +08:00

feat(date-picker): add year-range prop, closes

This commit is contained in:
07akioni 2024-08-11 22:38:38 +08:00
parent 3536bf009c
commit 6e1a9acc86
11 changed files with 54 additions and 28 deletions

@ -35,8 +35,9 @@
- `n-data-table` add `rowData` return for `render-expand-icon`, closes [#6108](https://github.com/tusen-ai/naive-ui/issues/6108)
- `n-empty` `size` prop to support `tiny` size.
- `n-config-provider` adds `style-mount-target` prop to control where to mount components' style.
- `n-cascader` filter ignore case sensitive
- `n-data-table` add allowExport prop for column
- `n-cascader` filter ignore case sensitive.
- `n-data-table` adds `allowExport` prop for column.
- `n-date-picker` adds `year-range` prop.
## 2.39.0

@ -36,7 +36,8 @@
- `n-empty` `size` 支持 `tiny` 尺寸
- `n-config-provider` 新增 `style-mount-target` 属性,用于控制样式的挂载位置
- `n-cascader` 过滤算法忽略大小写
- `n-data-table` 在列的配置中新增是否导出的属性
- `n-data-table` 在列的配置中新增 `allowExport` 属性
- `n-date-picker` 新增 `year-range` 属性
## 2.39.0

@ -59,6 +59,7 @@ panel.vue
| value | `number \| [number, number] \| null` | `undefined` | Value of the date picker when being manually set. | |
| value-format | `string` | Follow `format` prop | Format of the binding value. See [format](https://date-fns.org/v2.23.0/docs/format). | 2.24.0 |
| year-format | `string` | `'y'` | Format of year item in the panel. See [format](https://date-fns.org/v2.23.0/docs/format). | 2.37.0 |
| year-range | `[number, number]` | `[1901, 2100]` | Year range in month picker in panel. | NEXT_VERSION |
| on-clear | `() => void` | `undefined` | On clear callback. | 2.28.3 |
| on-confirm | `(value: number \| [number, number] \| null, formattedValue: string \| [string, string] \| null) => void` | `undefined` | On confirm callback. | 2.28.3 |
| on-blur | `() => void` | `undefined` | On blur callback. | |

@ -60,6 +60,7 @@ form-debug.vue
| value | `number \| [number, number] \| null` | `undefined` | Date Picker 的值 | |
| value-format | `string` | 跟随 `format` 属性 | 绑定值的格式,详情见 [format](https://date-fns.org/v2.23.0/docs/format) |
| year-format | `string` | `'y'` | 设置面板中年的显示方式,详情见 [format](https://date-fns.org/v2.23.0/docs/format) | 2.37.0 |
| year-range | `[number, number]` | `[1901, 2100]` | 设置面板中的年份选择范围 | NEXT_VERSION |
| on-clear | `() => void` | `undefined` | 用户 clear 时执行的回调 | 2.28.3 |
| on-confirm | `(value: number \| [number, number] \| null, formattedValue: string \| [string, string] \| null) => void` | `undefined` | 用户 confirm 时执行的回调 | 2.28.3 |
| on-blur | `() => void` | `undefined` | 用户 blur 时执行的回调 | |

@ -721,6 +721,7 @@ export default defineComponent({
monthFormatRef: toRef(props, 'monthFormat'),
yearFormatRef: toRef(props, 'yearFormat'),
quarterFormatRef: toRef(props, 'quarterFormat'),
yearRangeRef: toRef(props, 'yearRange'),
...uniVaidation,
...dualValidation,
datePickerSlots: slots

@ -1,4 +1,3 @@
export const START_YEAR = 1901
// TODO: we need to remove it to make height customizable
export const MONTH_ITEM_HEIGHT = 40

@ -136,6 +136,7 @@ export type DatePickerInjection = {
yearFormatRef: Ref<string>
quarterFormatRef: Ref<string>
datePickerSlots: Slots
yearRangeRef: Ref<[number, number]>
} & ReturnType<typeof uniCalendarValidation> &
ReturnType<typeof dualCalendarValidation>

@ -46,7 +46,7 @@ import type {
} from '../interface'
import { datePickerInjectionKey } from '../interface'
import type { DateItem, MonthItem, QuarterItem, YearItem } from '../utils'
import { MONTH_ITEM_HEIGHT, START_YEAR } from '../config'
import { MONTH_ITEM_HEIGHT } from '../config'
import { usePanelCommon, usePanelCommonProps } from './use-panel-common'
const useCalendarProps = {
@ -77,7 +77,8 @@ function useCalendar(
datePickerSlots,
yearFormatRef,
monthFormatRef,
quarterFormatRef
quarterFormatRef,
yearRangeRef
} = inject(datePickerInjectionKey)!
const validation = {
isValueInvalid: isValueInvalidRef,
@ -129,9 +130,14 @@ function useCalendar(
})
const yearArrayRef = computed(() => {
const { value } = props
return yearArray(Array.isArray(value) ? null : value, nowRef.value, {
yearFormat: yearFormatRef.value
})
return yearArray(
Array.isArray(value) ? null : value,
nowRef.value,
{
yearFormat: yearFormatRef.value
},
yearRangeRef
)
})
const quarterArrayRef = computed(() => {
const { value } = props
@ -517,7 +523,7 @@ function useCalendar(
? mergedValue === null
? getYear(Date.now())
: getYear(mergedValue as number)
: getYear(value)) - START_YEAR
: getYear(value)) - yearRangeRef.value[0]
yearVlRef.value.scrollTo({ top: yearIndex * MONTH_ITEM_HEIGHT })
}
}

@ -34,7 +34,7 @@ import {
datePickerInjectionKey
} from '../interface'
import type { ScrollbarInst } from '../../../_internal'
import { MONTH_ITEM_HEIGHT, START_YEAR } from '../config'
import { MONTH_ITEM_HEIGHT } from '../config'
import { usePanelCommon, usePanelCommonProps } from './use-panel-common'
const useDualCalendarProps = {
@ -80,7 +80,8 @@ function useDualCalendar(
datePickerSlots,
monthFormatRef,
yearFormatRef,
quarterFormatRef
quarterFormatRef,
yearRangeRef
} = inject(datePickerInjectionKey)!
const validation = {
isDateDisabled: isDateDisabledRef,
@ -225,14 +226,24 @@ function useDualCalendar(
return shortcuts || rangesRef.value
})
const startYearArrayRef = computed(() => {
return yearArray(pluckValueFromRange(props.value, 'start'), nowRef.value, {
yearFormat: yearFormatRef.value
})
return yearArray(
pluckValueFromRange(props.value, 'start'),
nowRef.value,
{
yearFormat: yearFormatRef.value
},
yearRangeRef
)
})
const endYearArrayRef = computed(() => {
return yearArray(pluckValueFromRange(props.value, 'end'), nowRef.value, {
yearFormat: yearFormatRef.value
})
return yearArray(
pluckValueFromRange(props.value, 'end'),
nowRef.value,
{
yearFormat: yearFormatRef.value
},
yearRangeRef
)
})
const startQuarterArrayRef = computed(() => {
const startValue = pluckValueFromRange(props.value, 'start')
@ -739,7 +750,7 @@ function useDualCalendar(
const yearIndex
= (!Array.isArray(mergedValue)
? getYear(Date.now())
: getYear(mergedValue[0])) - START_YEAR
: getYear(mergedValue[0])) - yearRangeRef.value[0]
startYearVlRef.value.scrollTo({ index: yearIndex, debounce: false })
}
}
@ -758,7 +769,7 @@ function useDualCalendar(
const yearIndex
= (!Array.isArray(mergedValue)
? getYear(Date.now())
: getYear(mergedValue[1])) - START_YEAR
: getYear(mergedValue[1])) - yearRangeRef.value[0]
endYearVlRef.value.scrollTo({ index: yearIndex, debounce: false })
}
}

@ -81,6 +81,10 @@ export const datePickerProps = {
monthFormat: { type: String, default: 'M' },
yearFormat: { type: String, default: 'y' },
quarterFormat: { type: String, default: '\'Q\'Q' },
yearRange: {
type: Array as unknown as PropType<[number, number]>,
default: (): [number, number] => [1901, 2100]
},
'onUpdate:show': [Function, Array] as PropType<
MaybeArray<(show: boolean) => void>
>,

@ -17,11 +17,12 @@ import {
isSameYear,
isValid,
parse,
setYear,
startOfMonth,
startOfYear
} from 'date-fns'
import type { Ref } from 'vue'
import type { NDateLocale } from '../../locales'
import { START_YEAR } from './config'
import type { FirstDayOfWeek, Value } from './interface'
function getDerivedTimeFromKeyboardEvent(
@ -451,16 +452,15 @@ function yearArray(
currentTs: number,
format: {
yearFormat: string
}
},
rangeRef: Ref<[number, number]>
): YearItem[] {
const range = rangeRef.value
const calendarYears: YearItem[] = []
const time1900 = new Date(START_YEAR, 0, 1)
// 1900 is not a round time, so we use 1911 as start...
// new Date(1900, 0, 1)
// 1899-12-31T15:54:17.000Z
for (let i = 0; i < 200; i++) {
const startTime = startOfYear(setYear(new Date(), range[0]))
for (let i = 0; i < range[1] - range[0]; i++) {
calendarYears.push(
yearItem(getTime(addYears(time1900, i)), valueTs, currentTs, format)
yearItem(getTime(addYears(startTime, i)), valueTs, currentTs, format)
)
}
return calendarYears