mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-03-07 13:48:31 +08:00
feat(date-picker): support year type (#1297)
* feat:n-input Support hidden password * feat(form): support require-mark-placement(#171) * Revert "feat(form): support require-mark-placement(#171)" This reverts commit0627777693
. * Revert "feat:n-input Support hidden password" This reverts commitea6491783d
. * test(dialog): Update dialog component test (#1404) * test(data-table): update test (#1411) * fix * Feat(date picker) support year type * format code * 修正代码 * 修正代码 * 去掉多余代码 * 去掉无用代码 * 修正代码 * 修改类型 * 修正代码 * Update src/date-picker/src/DatePicker.tsx Co-authored-by: Mr.Bai <935196116@qq.com> * Update src/date-picker/src/DatePicker.tsx * 修正代码 * checkbox: 简化代码 * add padding-bottom * changelog * Update Checkbox.tsx Co-authored-by: songjianet <1778651752@qq.com> Co-authored-by: XieZongChen <46394163+amadeus711@users.noreply.github.com> Co-authored-by: 07akioni <07akioni2@gmail.com> Co-authored-by: Mr.Bai <935196116@qq.com>
This commit is contained in:
parent
6c1024982c
commit
80dd6d6702
@ -12,6 +12,7 @@
|
||||
|
||||
- `n-menu` add a color distinction between selected and unselected arrow, closes [#1535](https://github.com/TuSimple/naive-ui/issues/1535).
|
||||
- `n-menu` 's `defaultExpandedKeys` use watchEffect initialize, closes [#1536](https://github.com/TuSimple/naive-ui/issues/1536).
|
||||
- `n-date-picker`'s `type` prop support `year` option.
|
||||
|
||||
## 2.20.2 (2021-11-05)
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
- `n-menu` 添加箭头颜色区分选中未选中,关闭 [#1535](https://github.com/TuSimple/naive-ui/issues/1535)
|
||||
- `n-menu` 的 `defaultExpandedKeys` 使用 watchEffect 初始化,关闭 [#1536](https://github.com/TuSimple/naive-ui/issues/1536)
|
||||
- `n-date-picker` 属性 `type` 支持 `year` 选项
|
||||
|
||||
## 2.20.2 (2021-11-05)
|
||||
|
||||
|
@ -29,6 +29,7 @@ import LineMark from './LineMark'
|
||||
import { checkboxGroupInjectionKey } from './CheckboxGroup'
|
||||
import type { OnUpdateChecked, OnUpdateCheckedImpl } from './interface'
|
||||
import style from './styles/index.cssr'
|
||||
import { on } from 'evtd'
|
||||
|
||||
const checkboxProps = {
|
||||
...(useTheme.props as ThemeProps<CheckboxTheme>),
|
||||
@ -310,13 +311,16 @@ export default defineComponent({
|
||||
onKeydown={handleKeyDown}
|
||||
onClick={handleClick}
|
||||
onMousedown={() => {
|
||||
const preventDefault = (e: Event): void => {
|
||||
e.preventDefault()
|
||||
}
|
||||
window.addEventListener('selectstart', preventDefault)
|
||||
setTimeout(() => {
|
||||
window.removeEventListener('selectstart', preventDefault)
|
||||
}, 0)
|
||||
on(
|
||||
'selectstart',
|
||||
window,
|
||||
(e: Event): void => {
|
||||
e.preventDefault()
|
||||
},
|
||||
{
|
||||
once: true
|
||||
}
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div class={`${mergedClsPrefix}-checkbox-box`}>
|
||||
|
@ -10,6 +10,7 @@ datetime
|
||||
daterange
|
||||
datetimerange
|
||||
month
|
||||
year
|
||||
size
|
||||
disabled
|
||||
disabled-time
|
||||
@ -34,7 +35,7 @@ update-on-close
|
||||
| input-readonly | `boolean` | `false` | Set the `readonly` attribute of the input (avoids virtual keyboard on touch devices). |
|
||||
| shortcuts | `Record<string, number \| (() => number)> \| Record<string, [number, number] \| (() => [number, number])>` | `undefined` | Shortcut button customizations. |
|
||||
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | Date picker size. |
|
||||
| type | `'date' \| 'datetime' \| 'daterange' \|'datetimerange' \|'month'` | `'date'` | Date picker type. |
|
||||
| type | `'date' \| 'datetime' \| 'daterange' \| 'datetimerange' \| 'month' \| 'year'` | `'date'` | Date picker type. |
|
||||
| value | `number \| [number, number] \| null` | `undefined` | Value of the date picker when being manually set. |
|
||||
| on-blur | `() => void` | `undefined` | On blur callback. |
|
||||
| on-focus | `() => void` | `undefined` | On focus callback. |
|
||||
|
18
src/date-picker/demos/enUS/year.demo.md
Normal file
18
src/date-picker/demos/enUS/year.demo.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Year
|
||||
|
||||
```html
|
||||
<n-date-picker v-model:value="timestamp" type="year" clearable />
|
||||
<pre>{{ JSON.stringify(timestamp) }}</pre>
|
||||
```
|
||||
|
||||
```js
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
timestamp: ref(1183135260000)
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
@ -10,6 +10,7 @@ datetime
|
||||
daterange
|
||||
datetimerange
|
||||
month
|
||||
year
|
||||
size
|
||||
disabled
|
||||
disabled-time
|
||||
@ -34,7 +35,7 @@ update-on-close
|
||||
| input-readonly | `boolean` | `false` | 设置输入框为只读(避免在移动设备上打开虚拟键盘) |
|
||||
| shortcuts | `Record<string, number \| (() => number)> \| Record<string, [number, number] \| (() => [number, number])>` | `undefined` | 自定义快捷按钮 |
|
||||
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | 尺寸 |
|
||||
| type | `'date' \| 'datetime' \| 'daterange' \|'datetimerange' \|'month'` | `'date'` | Date Picker 的类型 |
|
||||
| type | `'date' \| 'datetime' \| 'daterange' \| 'datetimerange' \| 'month' \| 'year'` | `'date'` | Date Picker 的类型 |
|
||||
| value | `number \| [number, number] \| null` | `undefined` | Date Picker 的值 |
|
||||
| on-blur | `() => void` | `undefined` | 用户 blur 时执行的回调 |
|
||||
| on-focus | `() => void` | `undefined` | 用户 focus 时执行的回调 |
|
||||
|
18
src/date-picker/demos/zhCN/year.demo.md
Normal file
18
src/date-picker/demos/zhCN/year.demo.md
Normal file
@ -0,0 +1,18 @@
|
||||
# 年份
|
||||
|
||||
```html
|
||||
<n-date-picker v-model:value="timestamp" type="year" clearable />
|
||||
<pre>{{ JSON.stringify(timestamp) }}</pre>
|
||||
```
|
||||
|
||||
```js
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
timestamp: ref(1183135260000)
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
@ -59,7 +59,8 @@ const DATE_FORMAT = {
|
||||
datetime: 'yyyy-MM-dd HH:mm:ss',
|
||||
daterange: 'yyyy-MM-dd',
|
||||
datetimerange: 'yyyy-MM-dd HH:mm:ss',
|
||||
month: 'yyyy-MM'
|
||||
month: 'yyyy-MM',
|
||||
year: 'yyyy'
|
||||
}
|
||||
|
||||
const datePickerProps = {
|
||||
@ -92,9 +93,7 @@ const datePickerProps = {
|
||||
value: [Number, Array] as PropType<Value | null>,
|
||||
size: String as PropType<'small' | 'medium' | 'large'>,
|
||||
type: {
|
||||
type: String as PropType<
|
||||
'date' | 'datetime' | 'daterange' | 'datetimerange' | 'month'
|
||||
>,
|
||||
type: String as PropType<keyof typeof DATE_FORMAT>,
|
||||
default: 'date'
|
||||
},
|
||||
separator: String,
|
||||
@ -260,6 +259,9 @@ export default defineComponent({
|
||||
case 'month': {
|
||||
return ['clear', 'now', 'confirm']
|
||||
}
|
||||
case 'year': {
|
||||
return ['clear', 'now']
|
||||
}
|
||||
default: {
|
||||
warn(
|
||||
'data-picker',
|
||||
@ -366,6 +368,7 @@ export default defineComponent({
|
||||
yearScrollRef.scrollTo({ top: yearIndex * MONTH_ITEM_HEIGHT })
|
||||
}
|
||||
}
|
||||
|
||||
// --- Panel update value
|
||||
function handlePanelUpdateValue (
|
||||
value: Value | null,
|
||||
@ -507,7 +510,7 @@ export default defineComponent({
|
||||
function openCalendar (): void {
|
||||
if (mergedDisabledRef.value || mergedShowRef.value) return
|
||||
doUpdateShow(true)
|
||||
if (props.type === 'month') {
|
||||
if (props.type === 'month' || props.type === 'year') {
|
||||
void nextTick(scrollYearMonth)
|
||||
}
|
||||
}
|
||||
@ -875,7 +878,17 @@ export default defineComponent({
|
||||
) : this.type === 'datetimerange' ? (
|
||||
<DatetimerangePanel {...commonPanelProps} />
|
||||
) : this.type === 'month' ? (
|
||||
<MonthPanel {...commonPanelProps} />
|
||||
<MonthPanel
|
||||
{...commonPanelProps}
|
||||
type="month"
|
||||
key="month"
|
||||
/>
|
||||
) : this.type === 'year' ? (
|
||||
<MonthPanel
|
||||
{...commonPanelProps}
|
||||
type="year"
|
||||
key="year"
|
||||
/>
|
||||
) : (
|
||||
<DatePanel {...commonPanelProps} />
|
||||
),
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { h, defineComponent, VNode } from 'vue'
|
||||
import { h, defineComponent, VNode, PropType } from 'vue'
|
||||
import { VirtualList } from 'vueuc'
|
||||
import { NButton, NxButton } from '../../../button'
|
||||
import { NBaseFocusDetector, NScrollbar } from '../../../_internal'
|
||||
@ -14,9 +14,15 @@ import { MONTH_ITEM_HEIGHT } from '../config'
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'MonthPanel',
|
||||
props: useCalendar.props,
|
||||
props: {
|
||||
...useCalendar.props,
|
||||
type: {
|
||||
type: String as PropType<'month' | 'year'>,
|
||||
default: 'date'
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
const useCalendarRef = useCalendar(props, 'month')
|
||||
const useCalendarRef = useCalendar(props, props.type)
|
||||
const renderItem = (
|
||||
item: YearItem | MonthItem,
|
||||
i: number,
|
||||
@ -51,8 +57,14 @@ export default defineComponent({
|
||||
return { ...useCalendarRef, renderItem }
|
||||
},
|
||||
render () {
|
||||
const { mergedClsPrefix, mergedTheme, shortcuts, actions, renderItem } =
|
||||
this
|
||||
const {
|
||||
mergedClsPrefix,
|
||||
mergedTheme,
|
||||
shortcuts,
|
||||
actions,
|
||||
renderItem,
|
||||
type
|
||||
} = this
|
||||
return (
|
||||
<div
|
||||
ref="selfRef"
|
||||
@ -81,6 +93,7 @@ export default defineComponent({
|
||||
showScrollbar={false}
|
||||
keyField="ts"
|
||||
onScroll={this.handleVirtualListScroll}
|
||||
paddingBottom={4}
|
||||
>
|
||||
{{
|
||||
default: ({
|
||||
@ -97,26 +110,28 @@ export default defineComponent({
|
||||
)
|
||||
}}
|
||||
</NScrollbar>
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__picker-col`}
|
||||
>
|
||||
<NScrollbar
|
||||
ref="monthScrollRef"
|
||||
theme={mergedTheme.peers.Scrollbar}
|
||||
themeOverrides={mergedTheme.peerOverrides.Scrollbar}
|
||||
{type === 'month' ? (
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__picker-col`}
|
||||
>
|
||||
{{
|
||||
default: () => [
|
||||
this.monthArray.map((monthItem, i) =>
|
||||
renderItem(monthItem, i, mergedClsPrefix)
|
||||
),
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__padding`}
|
||||
/>
|
||||
]
|
||||
}}
|
||||
</NScrollbar>
|
||||
</div>
|
||||
<NScrollbar
|
||||
ref="monthScrollRef"
|
||||
theme={mergedTheme.peers.Scrollbar}
|
||||
themeOverrides={mergedTheme.peerOverrides.Scrollbar}
|
||||
>
|
||||
{{
|
||||
default: () => [
|
||||
this.monthArray.map((monthItem, i) =>
|
||||
renderItem(monthItem, i, mergedClsPrefix)
|
||||
),
|
||||
<div
|
||||
class={`${mergedClsPrefix}-date-panel-month-calendar__padding`}
|
||||
/>
|
||||
]
|
||||
}}
|
||||
</NScrollbar>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
{this.datePickerSlots.footer ? (
|
||||
<div class={`${mergedClsPrefix}-date-panel-footer`}>
|
||||
|
@ -12,7 +12,8 @@ import {
|
||||
isValid,
|
||||
startOfDay,
|
||||
startOfSecond,
|
||||
startOfMonth
|
||||
startOfMonth,
|
||||
startOfYear
|
||||
} from 'date-fns'
|
||||
import { dateArray, monthArray, strictParse, yearArray } from '../utils'
|
||||
import { usePanelCommon } from './use-panel-common'
|
||||
@ -36,7 +37,7 @@ const useCalendarProps = {
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
function useCalendar (
|
||||
props: ExtractPropTypes<typeof useCalendarProps>,
|
||||
type: 'date' | 'datetime' | 'month'
|
||||
type: 'date' | 'datetime' | 'month' | 'year'
|
||||
) {
|
||||
const panelCommon = usePanelCommon(props)
|
||||
const {
|
||||
@ -139,6 +140,7 @@ function useCalendar (
|
||||
function sanitizeValue (value: number): number {
|
||||
if (type === 'datetime') return getTime(startOfSecond(value))
|
||||
if (type === 'month') return getTime(startOfMonth(value))
|
||||
if (type === 'year') return getTime(startOfYear(value))
|
||||
return getTime(startOfDay(value))
|
||||
}
|
||||
function mergedIsDateDisabled (ts: number): boolean {
|
||||
@ -219,12 +221,17 @@ function useCalendar (
|
||||
newValue = Date.now()
|
||||
}
|
||||
newValue = getTime(set(newValue, dateItem.dateObject))
|
||||
panelCommon.doUpdateValue(sanitizeValue(newValue), type === 'date')
|
||||
panelCommon.doUpdateValue(
|
||||
sanitizeValue(newValue),
|
||||
type === 'date' || type === 'year'
|
||||
)
|
||||
if (type === 'date') {
|
||||
panelCommon.doClose()
|
||||
} else if (type === 'month') {
|
||||
panelCommon.disableTransitionOneTick()
|
||||
scrollYearMonth(newValue)
|
||||
} else if (type === 'year') {
|
||||
panelCommon.doClose()
|
||||
}
|
||||
}
|
||||
function deriveDateInputValue (time?: number): void {
|
||||
|
@ -18,9 +18,11 @@ export default {
|
||||
calendarLeftPaddingDaterange: '6px 12px 4px 12px',
|
||||
calendarLeftPaddingDatetimerange: '4px 12px',
|
||||
calendarLeftPaddingMonth: '0',
|
||||
calendarLeftPaddingYear: '0',
|
||||
calendarRightPaddingDate: '6px 12px 4px 12px',
|
||||
calendarRightPaddingDatetime: '4px 12px',
|
||||
calendarRightPaddingDaterange: '6px 12px 4px 12px',
|
||||
calendarRightPaddingDatetimerange: '4px 12px',
|
||||
calendarRightPaddingMonth: '0'
|
||||
calendarRightPaddingMonth: '0',
|
||||
calendarRightPaddingYear: '0'
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user