@@ -37,6 +37,7 @@
import BScroll from 'better-scroll'
import CubePopup from '../popup/popup.vue'
import apiMixin from '../../common/mixins/api'
+ import basicPickerMixin from '../../common/mixins/basic-picker'
import pickerMixin from '../../common/mixins/picker'
const COMPONENT_NAME = 'cube-picker'
@@ -48,7 +49,7 @@
export default {
name: COMPONENT_NAME,
- mixins: [apiMixin, pickerMixin],
+ mixins: [apiMixin, basicPickerMixin, pickerMixin],
data() {
return {
pickerData: this.data.slice(),
diff --git a/src/index.js b/src/index.js
index 203a84a3dfcc80edaab6489e0259feb23e88dc97..b93837d522ded1df401767b249d076f62994e841 100644
--- a/src/index.js
+++ b/src/index.js
@@ -5,6 +5,7 @@ import {
Popup,
TimePicker,
SegmentPicker,
+ DatePicker,
Select,
Dialog,
Tip,
@@ -36,6 +37,7 @@ function install(Vue) {
Button,
TimePicker,
SegmentPicker,
+ DatePicker,
Select,
Dialog,
Tip,
diff --git a/src/module.js b/src/module.js
index 684c2883464adfc6ba5239914c064b553e55f340..b868254423b0c503d77275291bd229ed3bbbe5ce 100644
--- a/src/module.js
+++ b/src/module.js
@@ -20,6 +20,7 @@ import Slide from './modules/slide'
import IndexList from './modules/index-list'
import TimePicker from './modules/time-picker'
import SegmentPicker from './modules/segment-picker'
+import DatePicker from './modules/date-picker'
import Scroll from './modules/scroll'
import Upload from './modules/upload'
@@ -47,6 +48,7 @@ export {
TimePicker,
CascadePicker,
SegmentPicker,
+ DatePicker,
Select,
Form,
FormGroup,
diff --git a/src/modules/date-picker/api.js b/src/modules/date-picker/api.js
new file mode 100644
index 0000000000000000000000000000000000000000..49c048d0049df212f37ca92e85138f23897d92d2
--- /dev/null
+++ b/src/modules/date-picker/api.js
@@ -0,0 +1,11 @@
+import createAPI from '../../common/helpers/create-api'
+import { warn } from '../../common/helpers/debug'
+
+export default function addDatePicker (Vue, DatePicker) {
+ const datePickerAPI = createAPI(Vue, DatePicker, ['select', 'cancel', 'value-change'])
+ datePickerAPI.before((data, renderFn, single) => {
+ if (single) {
+ warn('DatePicker component can not be a singleton.')
+ }
+ })
+}
diff --git a/src/modules/date-picker/index.js b/src/modules/date-picker/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..77ad866f24d65f3a754d33ba4da23a63fe441136
--- /dev/null
+++ b/src/modules/date-picker/index.js
@@ -0,0 +1,15 @@
+import CascadePicker from '../../components/cascade-picker/cascade-picker.vue'
+import DatePicker from '../../components/date-picker/date-picker.vue'
+import addDatePicker from './api'
+import addCascadePicker from '../cascade-picker/api'
+
+DatePicker.install = function (Vue) {
+ Vue.component(CascadePicker.name, CascadePicker)
+ Vue.component(DatePicker.name, DatePicker)
+ addCascadePicker(Vue, CascadePicker)
+ addDatePicker(Vue, DatePicker)
+}
+
+DatePicker.CascadePicker = CascadePicker
+
+export default DatePicker
diff --git a/test/unit/specs/date-picker.spec.js b/test/unit/specs/date-picker.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..fe28818672deef5c07b3a2af86574b13d0945491
--- /dev/null
+++ b/test/unit/specs/date-picker.spec.js
@@ -0,0 +1,202 @@
+import Vue from 'vue2'
+import DatePicker from '@/modules/date-picker'
+import instantiateComponent from '@/common/helpers/instantiate-component'
+import { dispatchSwipe } from '../utils/event'
+
+describe('DatePicker', () => {
+ let vm
+
+ afterEach(() => {
+ if (vm) {
+ vm.$parent.destroy()
+ vm = null
+ }
+ })
+
+ it('use', () => {
+ Vue.use(DatePicker)
+ expect(Vue.component(DatePicker.name))
+ .to.be.a('function')
+ })
+
+ it('should render correct contents', function () {
+ vm = createDatePicker({
+ min: new Date(2008, 7, 8),
+ max: new Date(2020, 9, 20)
+ })
+
+ const wheels = vm.$el.querySelectorAll('.cube-picker-wheel-wrapper > div')
+ expect(wheels.length)
+ .to.equal(3)
+
+ const firstWheelItems = wheels[0].querySelectorAll('li')
+ expect(firstWheelItems.length)
+ .to.equal(13)
+ expect(firstWheelItems[1].textContent.trim())
+ .to.equal('2009年')
+
+ const secondWheelItems = wheels[1].querySelectorAll('li')
+ expect(secondWheelItems.length)
+ .to.equal(5)
+ expect(secondWheelItems[1].textContent.trim())
+ .to.equal('9月')
+
+ const thirdWheelItems = wheels[2].querySelectorAll('li')
+ expect(thirdWheelItems.length)
+ .to.equal(24)
+ expect(thirdWheelItems[1].textContent.trim())
+ .to.equal('9日')
+ })
+
+ it('should correct when configured startColumn and columnCount', function (done) {
+ this.timeout(10000)
+
+ vm = createDatePicker({
+ min: [1, 8],
+ max: [31, 23],
+ startColumn: 'date',
+ columnCount: 2
+ })
+
+ const wheels = vm.$el.querySelectorAll('.cube-picker-wheel-wrapper > div')
+ expect(wheels.length)
+ .to.equal(2)
+
+ const firstWheelItems = wheels[0].querySelectorAll('li')
+ expect(firstWheelItems.length)
+ .to.equal(31)
+ expect(firstWheelItems[1].textContent.trim())
+ .to.equal('2日')
+
+ const secondWheelItems = wheels[1].querySelectorAll('li')
+ expect(secondWheelItems.length)
+ .to.equal(16)
+ expect(secondWheelItems[1].textContent.trim())
+ .to.equal('9时')
+
+ // test: _arrayToDate if (i < this.beginIndex)
+ vm.show()
+ setTimeout(() => {
+ const confirmBtn = vm.$el.querySelector('.cube-picker-choose [data-action="confirm"]')
+ confirmBtn.click()
+ done()
+ }, 50)
+ })
+
+ it('should trigger events', function (done) {
+ this.timeout(10000)
+
+ const selectHandle = sinon.spy()
+ const cancelHandle = sinon.spy()
+ const changeHandle = sinon.spy()
+
+ vm = createDatePicker({
+ min: new Date(2008, 7, 8),
+ max: new Date(2020, 9, 20),
+ value: new Date(2010, 9, 1)
+ }, {
+ select: selectHandle,
+ cancel: cancelHandle,
+ change: changeHandle
+ })
+
+ vm.show()
+ setTimeout(() => {
+ const wheels = vm.$el.querySelectorAll('.cube-picker-wheel-wrapper > div')
+ const firstWheelItems = wheels[0].querySelectorAll('li')
+
+ // change
+ dispatchSwipe(firstWheelItems[1], [
+ {
+ pageX: firstWheelItems[1].offsetLeft + 10,
+ pageY: firstWheelItems[1].offsetTop + 10
+ },
+ {
+ pageX: 300,
+ pageY: 380
+ }
+ ], 100)
+
+ setTimeout(() => {
+ expect(changeHandle)
+ .to.be.callCount(1)
+
+ // select
+ const confirmBtn = vm.$el.querySelector('.cube-picker-choose [data-action="confirm"]')
+ confirmBtn.click()
+ expect(selectHandle)
+ .to.be.callCount(1)
+
+ // cancel
+ vm.show()
+ const cancelBtn = vm.$el.querySelector('.cube-picker-choose [data-action="cancel"]')
+ cancelBtn.click()
+ expect(cancelHandle)
+ .to.be.callCount(1)
+
+ done()
+ }, 1000)
+ }, 150)
+ })
+
+ it('should call methods', function (done) {
+ this.timeout(10000)
+
+ vm = createDatePicker()
+
+ // show
+ vm.show()
+
+ // hide
+ setTimeout(() => {
+ vm.hide()
+
+ done()
+ }, 100)
+ })
+
+ it('$updateProps', function (done) {
+ const selectHandle = sinon.spy()
+
+ vm = createDatePicker({
+ min: new Date(2008, 7, 8),
+ max: new Date(2020, 9, 20)
+ }, {
+ select: selectHandle
+ })
+
+ vm.$updateProps({
+ value: new Date(2010, 9, 1)
+ })
+
+ vm.show()
+ setTimeout(() => {
+ const confirmBtn = vm.$el.querySelector('.cube-picker-choose [data-action="confirm"]')
+ confirmBtn.click()
+ expect(selectHandle)
+ .to.be.calledWith(new Date(2010, 9, 1), [2010, 10, 1], ['2010年', '10月', '1日'])
+
+ done()
+ }, 100)
+ })
+
+ it('should add warn log when single is true', () => {
+ const app = new Vue()
+ const originWarn = console.warn
+ const msgs = []
+ console.warn = function (...args) {
+ msgs.push(args.join('#'))
+ }
+ vm = app.$createDatePicker({}, true)
+ expect(msgs.length)
+ .to.equal(1)
+ console.warn = originWarn
+ })
+
+ function createDatePicker(props = {}, events = {}) {
+ return instantiateComponent(Vue, DatePicker, {
+ props: props,
+ on: events
+ })
+ }
+})