feat(time-picker): step (#498)

* feat:add seconds , minutes, hours prop

* fix: modify according to conversation

* fix: modify according to conversation

* fix: modify according to conversation

* feat: optimization changelog

* Update src/time-picker/demos/zhCN/index.demo-entry.md

Co-authored-by: wuchouchou <w1301625107@gmail.com>
Co-authored-by: 07akioni <07akioni2@gmail.com>
This commit is contained in:
XieZongChen 2021-07-15 00:21:06 +08:00 committed by GitHub
parent 9c4997b461
commit 346ef47fa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 102 additions and 26 deletions

View File

@ -9,6 +9,7 @@
- `n-slider` add `format-tooltip` prop.
- `n-upload` add `event` in `on-finish` callback params.
- `n-rate` add `readonly` prop.
- `n-time-picker` add `seconds`, `minutes`, `hours` props.
- `n-notification` export `NotificationApi`, `NotificationOptions` and `NotificationReactive` type.
- `n-avatar` add `on-error` prop, closes [#394](https://github.com/TuSimple/naive-ui/issues/394).
- `n-image` add `on-error` prop, closes [#394](https://github.com/TuSimple/naive-ui/issues/394).

View File

@ -10,6 +10,7 @@
- `n-upload``on-finish` 回调参数中新增 `event`
- `n-slider` 新增 `format-tooltip` 属性
- `n-rate` 新增 `readonly` 属性
- `n-time-picker` 新增 `seconds`、`minutes`、`hours`属性
- `n-notification` 导出 `NotificationApi`, `NotificationOptions` and `NotificationReactive` 类型
- `n-avatar` 新增 `on-error` 属性,关闭[#394](https://github.com/TuSimple/naive-ui/issues/394)
- `n-image` 新增 `on-error` 属性,关闭[#394](https://github.com/TuSimple/naive-ui/issues/394)

View File

@ -8,6 +8,7 @@ Like a digital clock.
basic
size
disabled-time
step-time
format
```
@ -19,6 +20,9 @@ format
| default-value | `number \| null` | `null` | |
| disabled | `boolean` | `false` | |
| format | `string` | `'HH:mm:ss'` | |
| hours | `number \| number[]` | `undefined` | The hours to be displayed. If it's a number, it'll be viewed as step. |
| minutes | `number \| number[]` | `undefined` | The minutes to be displayed. If it's a number, it'll be viewed as step. |
| seconds | `number \| number[]` | `undefined` | The seconds to be displayed. If it's a number, it'll be viewed as step. |
| is-hour-disabled | `(hour: number) => boolean` | `() => false` | |
| is-minute-disabled | `(minute: number, hour: number) => boolean` | `() => false` | |
| is-second-disabled | `(second: number, minute: number, hour: number) => boolean` | `() => false` | |

View File

@ -0,0 +1,7 @@
# Step Time
Pass a number as step or use an array to specify the items you want to show.
```html
<n-time-picker :seconds="[0]" :hours="[8,18]" :minutes="30" />
```

View File

@ -8,6 +8,7 @@
basic
size
disabled-time
step-time
format
```
@ -19,6 +20,9 @@ format
| default-value | `number \| null` | `null` | |
| disabled | `boolean` | `false` | |
| format | `string` | `'HH:mm:ss'` | |
| hours | `number \| number[]` | `undefined` | 通过数组指定显示的小时。当值为 number 时,将被当做时间步进处理 |
| minutes | `number \| number[]` | `undefined` | 通过数组指定显示的分钟。当值为 number 时,将被当做时间步进处理 |
| seconds | `number \| number[]` | `undefined` | 通过数组指定显示的秒。当值为 number 时,将被当做时间步进处理 |
| is-hour-disabled | `(hour: number) => boolean` | `() => false` | |
| is-minute-disabled | `(minute: number, hour: number) => boolean` | `() => false` | |
| is-second-disabled | `(second: number, minute: number, hour: number) => boolean` | `() => false` | |

View File

@ -0,0 +1,7 @@
# 展示某些时间
传递单独的数字来定义时间步进或用数组指定你需要显示的内容。
```html
<n-time-picker :seconds="[0]" :hours="[8,18]" :minutes="30" />
```

View File

@ -2,7 +2,7 @@ import { h, ref, defineComponent, inject, PropType, computed } from 'vue'
import { NScrollbar } from '../../scrollbar'
import { NButton } from '../../button'
import { NBaseFocusDetector } from '../../_internal'
import { time } from './utils'
import { time, getFixValue } from './utils'
import {
IsHourDisabled,
IsMinuteDisabled,
@ -10,6 +10,7 @@ import {
timePickerInjectionKey
} from './interface'
import PanelCol, { Item } from './PanelCol'
import { MaybeArray } from '../../_utils'
export default defineComponent({
name: 'TimePickerPanel',
@ -84,7 +85,10 @@ export default defineComponent({
onFocusin: Function as PropType<(e: FocusEvent) => void>,
onFocusout: Function as PropType<(e: FocusEvent) => void>,
onFocusDetectorFocus: Function as PropType<() => void>,
onKeydown: Function as PropType<(e: KeyboardEvent) => void>
onKeydown: Function as PropType<(e: KeyboardEvent) => void>,
hours: [Number, Array] as PropType<MaybeArray<number>>,
minutes: [Number, Array] as PropType<MaybeArray<number>>,
seconds: [Number, Array] as PropType<MaybeArray<number>>
},
setup (props) {
const {
@ -92,18 +96,34 @@ export default defineComponent({
mergedClsPrefixRef
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
} = inject(timePickerInjectionKey)!
const hoursRef = computed<Item[]>(() =>
time.hours.map((hour) => {
const { isHourDisabled } = props
function getTimeUnits (
defaultValue: string[],
stepOrList: MaybeArray<number> | undefined
): string[] {
if (Array.isArray(stepOrList)) {
return stepOrList.map((v) => Math.floor(v)).map((v) => getFixValue(v))
} else if (typeof stepOrList === 'number') {
return defaultValue.filter((hour) => Number(hour) % stepOrList === 0)
} else {
return defaultValue
}
}
const hoursRef = computed<Item[]>(() => {
const { isHourDisabled, hours } = props
return getTimeUnits(time.hours, hours).map((hour) => {
return {
value: hour,
disabled: isHourDisabled ? isHourDisabled(Number(hour)) : false
}
})
)
const minutesRef = computed<Item[]>(() =>
time.minutes.map((minute) => {
const { isMinuteDisabled } = props
})
const minutesRef = computed<Item[]>(() => {
const { isMinuteDisabled, minutes } = props
return getTimeUnits(time.minutes, minutes).map((minute) => {
return {
value: minute,
disabled: isMinuteDisabled
@ -111,10 +131,11 @@ export default defineComponent({
: false
}
})
)
const secondsRef = computed<Item[]>(() =>
time.seconds.map((second) => {
const { isSecondDisabled } = props
})
const secondsRef = computed<Item[]>(() => {
const { isSecondDisabled, seconds } = props
return getTimeUnits(time.seconds, seconds).map((second) => {
return {
value: second,
disabled: isSecondDisabled
@ -126,7 +147,7 @@ export default defineComponent({
: false
}
})
)
})
return {
mergedTheme: mergedThemeRef,
mergedClsPrefix: mergedClsPrefixRef,
@ -156,10 +177,10 @@ export default defineComponent({
class={[
`${mergedClsPrefix}-time-picker-col`,
{
[`${mergedClsPrefix}-time-picker-col--invalid`]: this
.isHourInvalid,
[`${mergedClsPrefix}-time-picker-col--transition-disabled`]: this
.transitionDisabled
[`${mergedClsPrefix}-time-picker-col--invalid`]:
this.isHourInvalid,
[`${mergedClsPrefix}-time-picker-col--transition-disabled`]:
this.transitionDisabled
}
]}
>
@ -189,10 +210,10 @@ export default defineComponent({
class={[
`${mergedClsPrefix}-time-picker-col`,
{
[`${mergedClsPrefix}-time-picker-col--transition-disabled`]: this
.transitionDisabled,
[`${mergedClsPrefix}-time-picker-col--invalid`]: this
.isMinuteInvalid
[`${mergedClsPrefix}-time-picker-col--transition-disabled`]:
this.transitionDisabled,
[`${mergedClsPrefix}-time-picker-col--invalid`]:
this.isMinuteInvalid
}
]}
>
@ -222,10 +243,10 @@ export default defineComponent({
class={[
`${mergedClsPrefix}-time-picker-col`,
{
[`${mergedClsPrefix}-time-picker-col--invalid`]: this
.isSecondInvalid,
[`${mergedClsPrefix}-time-picker-col--transition-disabled`]: this
.transitionDisabled
[`${mergedClsPrefix}-time-picker-col--invalid`]:
this.isSecondInvalid,
[`${mergedClsPrefix}-time-picker-col--transition-disabled`]:
this.transitionDisabled
}
]}
>

View File

@ -59,6 +59,18 @@ import {
} from './interface'
import { happensIn } from 'seemly'
// validate hours,minutes,seconds prop
function validateUnits (value: MaybeArray<number>, max: number): boolean {
if (value === undefined) {
return true
}
if (Array.isArray(value)) {
return value.every((v) => v >= 0 && v <= max)
} else {
return value >= 0 && value <= max
}
}
const timePickerProps = {
...(useTheme.props as ThemeProps<TimePickerTheme>),
to: useAdjustedTo.propTo,
@ -119,6 +131,18 @@ const timePickerProps = {
return true
},
default: undefined
},
hours: {
type: [Number, Array] as PropType<MaybeArray<number>>,
validator: (value: MaybeArray<number>) => validateUnits(value, 23)
},
minutes: {
type: [Number, Array] as PropType<MaybeArray<number>>,
validator: (value: MaybeArray<number>) => validateUnits(value, 59)
},
seconds: {
type: [Number, Array] as PropType<MaybeArray<number>>,
validator: (value: MaybeArray<number>) => validateUnits(value, 59)
}
}
@ -666,6 +690,9 @@ export default defineComponent({
<Panel
ref="panelInstRef"
style={this.cssVars as CSSProperties}
seconds={this.seconds}
minutes={this.minutes}
hours={this.hours}
transitionDisabled={this.transitionDisabled}
hourValue={this.hourValue}
showHour={this.hourInFormat}

View File

@ -151,3 +151,7 @@ export const time = {
],
period: ['AM', 'PM']
}
export function getFixValue (value: number): string {
return `00${value}`.slice(-2)
}