未验证 提交 7532b40b 编写于 作者: A Amy 提交者: GitHub

feat(time-picker): support minuteStep rule (#252)

* feat: minute step rule

* docs: chinese

* fix: number value

* test: minuteStep

* docs: update

* fix: min hour change caused by ceil

* test: add case
上级 a059568c
......@@ -126,6 +126,49 @@ __注:__ 由于此组件基于 create-api 实现,所以在使用之前,请
}
```
- 分钟数的步长
通过 `minuteStep` 属性可配置分钟数的步长,默认为 10 分钟,这样的话,可选的分钟就是 10、20、30、40、50。另外在 v1.10.5+,`minuteStep` 还支持传入一个对象,你可以通过子属性 `rule` 配置取整的规则,是向上取整 `ceil`,向下取整 `floor`,又或是四舍五入`round`。而子属性 `step` 则代表步长。
```html
<cube-button @click="showMinuteStepPicker">Config minute step</cube-button>
```
```js
export default {
methods: {
showFormatPicker() {
if (!this.minuteStepPicker) {
this.minuteStepPicker = this.$createTimePicker({
minuteStep: {
rule: 'ceil',
step: 15
},
onSelect: this.selectHandler,
onCancel: this.cancelHandler
})
}
this.minuteStepPicker.show()
},
selectHandler(selectedTime, selectedText, formatedTime) {
this.$createDialog({
type: 'warn',
title: `selected time: ${selectedTime}`,
content: `selected text: ${selectedText}<br>format time: ${formatedTime}`,
icon: 'cubeic-alert'
}).show()
},
cancelHandler() {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
}
}
```
- 手动设置时间
```html
<cube-button @click="showTimePicker">TimePicker - setTime(next hour)</cube-button>
......@@ -177,7 +220,7 @@ __注:__ 由于此组件基于 create-api 实现,所以在使用之前,请
| delay | 将当前时间向后推算的分钟数,决定了最小可选时间 | Number | 15 |
| day | 日期配置 | Object | { len: 3, filter: ['今日'], format: 'M月D日' } |
| showNow | 是否显示现在;以及现在选项的文案<sup>1.9.0</sup> | Boolean, Object<sup>1.9.0</sup> | true |
| minuteStep | 分钟数的步长 | Number | 10 |
| minuteStep | 分钟数的步长。 当为 Object 时还可以配置取整规则,详见后续 `minuteStep` 子配置项说明<sup>1.10.5</sup> | Number, Object<sup>1.10.5</sup> | 10 |
| title | 标题 | String | '选择时间' |
| subtitle<sup>1.8.1</sup> | 副标题 | String | '' |
| cancelTxt<sup>1.8.1</sup> | 取消按钮文案 | String | '取消' |
......@@ -195,11 +238,18 @@ __注:__ 由于此组件基于 create-api 实现,所以在使用之前,请
| filter | 日期列,将时间映射为filter中的文案内容 | Array | ['今日'] |
| format | 时间格式化 | String | 'M月D日' |
* `showNow` 子配置项
* `showNow` 子配置项<sup>1.9.0</sup>
| 参数 | 说明 | 类型 | 默认值 |
| - | - | - | - |
| text<sup>1.9.0</sup> | 现在选项的文案 | String | '现在' |
| text | 现在选项的文案 | String | '现在' |
* `minuteStep` 子配置项<sup>1.10.5</sup>
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| rule | 取整的规则 | String | floor/ceil/round | 'floor' |
| step | 分钟数的步长 | Number | - | 10 |
### 事件
......
......@@ -5,6 +5,7 @@
<cube-button @click="showTimePicker">TimePicker</cube-button>
<cube-button @click="showConfigDayPicker">Config day options</cube-button>
<cube-button @click="showFormatPicker">Config format</cube-button>
<cube-button @click="showMinuteStepPicker">Config minute step</cube-button>
<cube-button @click="showSetTimePiker">Use setTime</cube-button>
</cube-button-group>
</div>
......@@ -55,6 +56,19 @@
}
this.formatPicker.show()
},
showMinuteStepPicker() {
if (!this.minuteStepPicker) {
this.minuteStepPicker = this.$createTimePicker({
minuteStep: {
rule: 'ceil',
step: 15
},
onSelect: this.selectHandler,
onCancel: this.cancelHandler
})
}
this.minuteStepPicker.show()
},
showSetTimePiker() {
if (!this.setTimePiker) {
this.setTimePiker = this.$createTimePicker({
......
......@@ -42,6 +42,14 @@
defaultText: '现在'
}
const INT_RULE = {
floor: 'floor',
ceil: 'ceil',
round: 'round'
}
const DEFAULT_STEP = 10
export default {
name: COMPONENT_NAME,
mixins: [visibilityMixin, popupMixin, pickerMixin],
......@@ -72,8 +80,8 @@
default: true
},
minuteStep: {
type: Number,
default: 10
type: [Number, Object],
default: DEFAULT_STEP
},
format: {
type: String,
......@@ -91,8 +99,25 @@
nowText() {
return (this.showNow && this.showNow.text) || NOW.defaultText
},
minuteStepRule() {
const minuteStep = this.minuteStep
return (typeof minuteStep === 'object' && Math[INT_RULE[minuteStep.rule]]) || Math[INT_RULE.floor]
},
minuteStepNumber() {
const minuteStep = this.minuteStep
return typeof minuteStep === 'number' ? minuteStep : (minuteStep.step || DEFAULT_STEP)
},
minTime() {
return new Date(+this.now + this.delay * MINUTE_TIMESTAMP)
let minTimeStamp = +this.now + this.delay * MINUTE_TIMESTAMP
// Handle the minTime selectable change caused by minute step.
const minute = new Date(minTimeStamp).getMinutes()
const intMinute = this.minuteStepRule(minute / this.minuteStepNumber) * this.minuteStepNumber
if (intMinute >= 60) {
minTimeStamp += (60 - minute) * MINUTE_TIMESTAMP
}
return new Date(minTimeStamp)
},
days() {
const days = []
......@@ -133,7 +158,7 @@
},
minutes() {
const minutes = []
for (let i = 0; i < 60; i += this.minuteStep) {
for (let i = 0; i < 60; i += this.minuteStepNumber) {
minutes.push({
value: i,
text: pad(i) + ''
......@@ -142,7 +167,7 @@
return minutes
},
partMinutes() {
const begin = Math.floor(this.minTime.getMinutes() / this.minuteStep)
const begin = this.minuteStepRule(this.minTime.getMinutes() / this.minuteStepNumber)
return this.minutes.slice(begin)
},
cascadeData() {
......@@ -192,9 +217,9 @@
const hourIndex = hour - beginHour
// calculate minuteIndex
const minute = Math.floor(valueDate.getMinutes() / this.minuteStep)
const minute = this.minuteStepRule(valueDate.getMinutes() / this.minuteStepNumber)
const beginMinute = !dayIndex && (this.showNow ? hourIndex === 1 : !hourIndex)
? Math.floor(this.minTime.getMinutes() / this.minuteStep)
? this.minuteStepRule(this.minTime.getMinutes() / this.minuteStepNumber)
: 0
const minuteIndex = minute - beginMinute
......
......@@ -233,6 +233,45 @@ describe('TimePicker', () => {
.to.equal(1)
console.warn = originWarn
})
testMinuteStep()
function testMinuteStep() {
const minuteStepConfigs = [
undefined,
15, {
rule: 'ceil'
}, {
step: 15
}, {
rule: 'floor',
step: 5
}, {
rule: 'ceil',
step: 8
}, {
rule: 'round',
step: 10
}
]
minuteStepConfigs.forEach((item) => {
it(`should init minutes correct when minute step is ${item}`, function () {
vm = createPicker({
showNow: false,
delay: 0,
minuteStep: item,
format: 'h:m'
})
const step = (typeof item === 'number' ? item : (item && item.step)) || 10
const rule = (item && item.rule) || 'floor'
expect(vm.partMinutes[0].value)
.to.equal(Math[rule](vm.minTime.getMinutes() / step) * step)
})
})
}
})
function createPicker(props = {}, events = {}) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册