Skip to content

Commit

Permalink
feat(time-picker): add use-12-hours prop, closes #547
Browse files Browse the repository at this point in the history
  • Loading branch information
07akioni committed Oct 17, 2021
1 parent 134aa49 commit 1661e2e
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 120 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

- `n-menu` add `dropdown-props` prop, closes [#1345](https://github.com/TuSimple/naive-ui/issues/1345).
- `n-input` add `count` slot, closes [#1314](https://github.com/TuSimple/naive-ui/issues/1314).
- `n-time-picker` add `use-12-hours` prop, closes [#547](https://github.com/TuSimple/naive-ui/issues/547).

## 2.19.8 (2021-10-14)

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

- `n-menu` 新增 `dropdown-props` 属性,关闭 [#1345](https://github.com/TuSimple/naive-ui/issues/1345)
- `n-input` 新增 `count` slot,关闭 [#1314](https://github.com/TuSimple/naive-ui/issues/1314)
- `n-time-picker` 新增 `use-12-hours` 属性,关闭 [#547](https://github.com/TuSimple/naive-ui/issues/547)

## 2.19.8 (2021-10-14)

Expand Down
2 changes: 1 addition & 1 deletion src/time-picker/demos/enUS/disabled-time.demo.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Disable Time
# Disable time

You can disable some time.

Expand Down
8 changes: 8 additions & 0 deletions src/time-picker/demos/enUS/hours12.demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 12 hours

```html
<n-space>
<n-time-picker use-12-hours />
<n-time-picker use-12-hours :default-value="1183135260000" />
</n-space>
```
2 changes: 2 additions & 0 deletions src/time-picker/demos/enUS/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ disabled-time
step-time
format
actions
hours12
```

## API
Expand All @@ -33,6 +34,7 @@ actions
| is-second-disabled | `(second: number, minute: number, hour: number) => boolean` | `() => false` | Callback function for disabling seconds. |
| placeholder | `string` | `'Select Time'` | Placeholder. |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | Size. |
| use-12-hours | `boolean` | `false` | Whether to use 12-hour clock panel. |
| value | `number \| null` | `undefined` | Value in controlled mode. |
| on-blur | `() => void` | `undefined` | Callback when the selection box loses focus. |
| on-focus | `() => void` | `undefined` | Callback when the selection box gets focus. |
Expand Down
2 changes: 1 addition & 1 deletion src/time-picker/demos/enUS/step-time.demo.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Step Time
# Step time

Pass a number as step or use an array to specify the items you want to show, inputting values that don't follow step settings will cause displaying invalid status.

Expand Down
8 changes: 8 additions & 0 deletions src/time-picker/demos/zhCN/hours12.demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 12 小时

```html
<n-space>
<n-time-picker use-12-hours />
<n-time-picker use-12-hours :default-value="1183135260000" />
</n-space>
```
2 changes: 2 additions & 0 deletions src/time-picker/demos/zhCN/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ disabled-time
step-time
format
actions
hours12
```

## API
Expand All @@ -33,6 +34,7 @@ actions
| is-second-disabled | `(second: number, minute: number, hour: number) => boolean` | `() => false` | 用于禁用秒钟的回调函数 |
| placeholder | `string` | `'Select Time'` | 选择框的占位符 |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | 选择框的尺寸 |
| use-12-hours | `boolean` | `false` | 是否使用 12 小时制的面板 |
| value | `number \| null` | `undefined` | 受控模式下的值 |
| on-blur | `() => void` | `undefined` | 选择框失去焦点时的回调 |
| on-focus | `() => void` | `undefined` | 选择框获得焦点时的回调 |
Expand Down
184 changes: 134 additions & 50 deletions src/time-picker/src/Panel.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { h, ref, defineComponent, inject, PropType, computed } from 'vue'
import { NScrollbar, NBaseFocusDetector } from '../../_internal'
import { NButton } from '../../button'
import { getTimeUnits, time } from './utils'
import { getTimeUnits, time, getAmPm } from './utils'
import {
IsHourDisabled,
IsMinuteDisabled,
IsSecondDisabled,
ItemValue,
Item,
timePickerInjectionKey
} from './interface'
import PanelCol, { Item } from './PanelCol'
import PanelCol from './PanelCol'
import { MaybeArray } from '../../_utils'

const timePickerPanelProps = {
Expand All @@ -35,6 +37,7 @@ const timePickerPanelProps = {
isHourInvalid: Boolean,
isMinuteInvalid: Boolean,
isSecondInvalid: Boolean,
isAmPmInvalid: Boolean,
isValueInvalid: Boolean,
hourValue: {
type: Number as PropType<number | null>,
Expand All @@ -48,19 +51,27 @@ const timePickerPanelProps = {
type: Number as PropType<number | null>,
default: null
},
amPmValue: {
type: String as PropType<'am' | 'pm' | null>,
default: null
},
isHourDisabled: Function as PropType<IsHourDisabled>,
isMinuteDisabled: Function as PropType<IsMinuteDisabled>,
isSecondDisabled: Function as PropType<IsSecondDisabled>,
onHourClick: {
type: Function as PropType<(value: number) => void>,
type: Function as PropType<(value: ItemValue) => void>,
required: true
},
onMinuteClick: {
type: Function as PropType<(value: number) => void>,
type: Function as PropType<(value: ItemValue) => void>,
required: true
},
onSecondClick: {
type: Function as PropType<(value: number) => void>,
type: Function as PropType<(value: ItemValue) => void>,
required: true
},
onAmPmClick: {
type: Function as PropType<(value: ItemValue) => void>,
required: true
},
onNowClick: Function as PropType<() => void>,
Expand All @@ -74,7 +85,8 @@ const timePickerPanelProps = {
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>>
seconds: [Number, Array] as PropType<MaybeArray<number>>,
use12Hours: Boolean
}

export default defineComponent({
Expand All @@ -88,21 +100,39 @@ export default defineComponent({
} = inject(timePickerInjectionKey)!

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 { isHourDisabled, hours, use12Hours, amPmValue } = props
if (!use12Hours) {
return getTimeUnits(time.hours, hours).map((hour) => {
return {
label: hour,
value: Number(hour),
disabled: isHourDisabled ? isHourDisabled(Number(hour)) : false
}
})
} else {
const mergedAmPmValue = amPmValue ?? getAmPm(Date.now())
return getTimeUnits(time.hours, hours, mergedAmPmValue).map((hour) => {
const hourAs12FormattedNumber = Number(hour)
const hourAs24FormattedNumber =
mergedAmPmValue === 'pm' && hourAs12FormattedNumber !== 12
? hourAs12FormattedNumber + 12
: hourAs12FormattedNumber
return {
label: hour,
value: hourAs24FormattedNumber,
disabled: isHourDisabled
? isHourDisabled(hourAs24FormattedNumber)
: false
}
})
}
})
const minutesRef = computed<Item[]>(() => {
const { isMinuteDisabled, minutes } = props

return getTimeUnits(time.minutes, minutes).map((minute) => {
return {
value: minute,
label: minute,
value: Number(minute),
disabled: isMinuteDisabled
? isMinuteDisabled(Number(minute), props.hourValue)
: false
Expand All @@ -111,10 +141,10 @@ export default defineComponent({
})
const secondsRef = computed<Item[]>(() => {
const { isSecondDisabled, seconds } = props

return getTimeUnits(time.seconds, seconds).map((second) => {
return {
value: second,
label: second,
value: Number(second),
disabled: isSecondDisabled
? isSecondDisabled(
Number(second),
Expand All @@ -125,40 +155,67 @@ export default defineComponent({
}
})
})
const amPmRef = computed<Item[]>(() => {
const { isHourDisabled } = props
let amDisabled = true
let pmDisabled = true
for (let i = 0; i < 12; ++i) {
if (!isHourDisabled?.(i)) {
amDisabled = false
break
}
}
for (let i = 12; i < 24; ++i) {
if (!isHourDisabled?.(i)) {
pmDisabled = false
break
}
}
return [
{
label: 'AM',
value: 'am',
disabled: amDisabled
},
{
label: 'PM',
value: 'pm',
disabled: pmDisabled
}
]
})
return {
mergedTheme: mergedThemeRef,
mergedClsPrefix: mergedClsPrefixRef,
hours: hoursRef,
minutes: minutesRef,
seconds: secondsRef,
amPm: amPmRef,
hourScrollRef: ref(null),
minuteScrollRef: ref(null),
secondScrollRef: ref(null)
secondScrollRef: ref(null),
amPmScrollRef: ref(null)
}
},
render () {
const { mergedClsPrefix, mergedTheme } = this
return h(
'div',
{
tabindex: 0,
class: `${mergedClsPrefix}-time-picker-panel`,
onFocusin: this.onFocusin,
onFocusout: this.onFocusout,
onKeydown: this.onKeydown
},
[
return (
<div
tabindex={0}
class={`${mergedClsPrefix}-time-picker-panel`}
onFocusin={this.onFocusin}
onFocusout={this.onFocusout}
onKeydown={this.onKeydown}
>
<div class={`${mergedClsPrefix}-time-picker-cols`}>
{this.showHour ? (
<div
class={[
`${mergedClsPrefix}-time-picker-col`,
{
[`${mergedClsPrefix}-time-picker-col--invalid`]:
this.isHourInvalid,
[`${mergedClsPrefix}-time-picker-col--transition-disabled`]:
this.transitionDisabled
}
this.isHourInvalid &&
`${mergedClsPrefix}-time-picker-col--invalid`,
this.transitionDisabled &&
`${mergedClsPrefix}-time-picker-col--transition-disabled`
]}
>
<NScrollbar
Expand Down Expand Up @@ -186,12 +243,10 @@ export default defineComponent({
<div
class={[
`${mergedClsPrefix}-time-picker-col`,
{
[`${mergedClsPrefix}-time-picker-col--transition-disabled`]:
this.transitionDisabled,
[`${mergedClsPrefix}-time-picker-col--invalid`]:
this.isMinuteInvalid
}
this.transitionDisabled &&
`${mergedClsPrefix}-time-picker-col--transition-disabled`,
this.isMinuteInvalid &&
`${mergedClsPrefix}-time-picker-col--invalid`
]}
>
<NScrollbar
Expand Down Expand Up @@ -219,12 +274,10 @@ export default defineComponent({
<div
class={[
`${mergedClsPrefix}-time-picker-col`,
{
[`${mergedClsPrefix}-time-picker-col--invalid`]:
this.isSecondInvalid,
[`${mergedClsPrefix}-time-picker-col--transition-disabled`]:
this.transitionDisabled
}
this.isSecondInvalid &&
`${mergedClsPrefix}-time-picker-col--invalid`,
this.transitionDisabled &&
`${mergedClsPrefix}-time-picker-col--transition-disabled`
]}
>
<NScrollbar
Expand All @@ -248,7 +301,38 @@ export default defineComponent({
</NScrollbar>
</div>
) : null}
</div>,
{this.use12Hours ? (
<div
class={[
`${mergedClsPrefix}-time-picker-col`,
this.isAmPmInvalid &&
`${mergedClsPrefix}-time-picker-col--invalid`,
this.transitionDisabled &&
`${mergedClsPrefix}-time-picker-col--transition-disabled`
]}
>
<NScrollbar
ref="amPmScrollRef"
theme={mergedTheme.peers.Scrollbar}
themeOverrides={mergedTheme.peerOverrides.Scrollbar}
>
{{
default: () => [
<PanelCol
clsPrefix={mergedClsPrefix}
data={this.amPm}
activeValue={this.amPmValue}
onItemClick={this.onAmPmClick}
/>,
<div
class={`${mergedClsPrefix}-time-picker-col__padding`}
/>
]
}}
</NScrollbar>
</div>
) : null}
</div>
<div class={`${mergedClsPrefix}-time-picker-actions`}>
{this.actions?.includes('now') ? (
<NButton
Expand All @@ -273,9 +357,9 @@ export default defineComponent({
{{ default: () => this.confirmText }}
</NButton>
) : null}
</div>,
</div>
<NBaseFocusDetector onFocus={this.onFocusDetectorFocus} />
]
</div>
)
}
})
Loading

0 comments on commit 1661e2e

Please sign in to comment.