feat(date-picker): change & blur events & some keyboard bindings

This commit is contained in:
07akioni 2019-10-30 16:22:17 +08:00
parent ad240f2b3f
commit ad76b5736e
12 changed files with 187 additions and 61 deletions

View File

@ -0,0 +1,76 @@
# Events
```html
<n-date-picker
v-model="datetime"
type="datetime"
:disabled="disabled"
@blur="onBlur1"
@change="onChange1"
/>
<n-date-picker
v-model="date"
type="date"
:disabled="disabled"
@blur="onBlur2"
@change="onChange2"
/>
<n-date-picker
v-model="datetimerange"
:disabled="disabled"
type="datetimerange"
@blur="onBlur3"
@change="onChange3"
/>
<n-date-picker
v-model="daterange"
:disabled="disabled"
type="daterange"
@blur="onBlur4"
@change="onChange4"
/>
<n-switch v-model="disabled" />
```
```js
export default {
data() {
return {
datetime: 891360258000,
date: null,
datetimerange: [324910284, 910391323],
daterange: [324910284, 910391323],
disabled: false
};
},
methods: {
onBlur1 (v) {
this.$NMessage.info('Blur1 ' + v)
},
onChange1 (v) {
this.$NMessage.info('Change1 ' + v)
},
onBlur2 (v) {
this.$NMessage.error('Blur2 ' + v)
},
onChange2 (v) {
this.$NMessage.error('Change2 ' + v)
},
onBlur3 (v) {
this.$NMessage.warning('Blur3 ' + v)
},
onChange3 (v) {
this.$NMessage.warning('Change3 ' + v)
},
onBlur4 (v) {
this.$NMessage.success('Blur4 ' + v)
},
onChange4 (v) {
this.$NMessage.success('Change4 ' + v)
}
}
};
```
```css
.n-date-picker {
margin: 0 12px 8px 0;
}
```

View File

@ -6,4 +6,5 @@ daterange
datetimerange
disabled
actions
events
```

View File

@ -10,12 +10,15 @@
>
<n-input
v-if="isRange"
ref="input"
:lazy-focus="true"
:disabled="disabled"
:value="[displayStartTime, displayEndTime]"
:placeholder="[computedStartPlaceholder, computedEndPlaceholder]"
:readonly="disabled ? 'disabled' : false"
:splitor="splitor"
split
:seperator="seperator"
:force-focus="active"
pair
@click="handleActivatorClick"
@focus="handleFocus"
@blur="handleRangeInputBlur"
@ -27,9 +30,12 @@
</n-input>
<n-input
v-else
ref="input"
v-model="displayTime"
class="n-date-picker__input"
:force-focus="active"
:disabled="disabled"
:lazy-focus="true"
:placeholder="computedPlaceholder"
:readonly="disabled ? 'disabled' : false"
@click="handleActivatorClick"
@ -60,6 +66,7 @@
:active="active"
:actions="actions"
:theme="synthesizedTheme"
@blur="handlePanelBlur"
@input="handlePanelInput"
@close="closeCalendar"
/>
@ -71,6 +78,7 @@
:actions="actions"
:theme="synthesizedTheme"
@input="handlePanelInput"
@blur="handlePanelBlur"
@close="closeCalendar"
/>
<daterange-panel
@ -81,6 +89,7 @@
:actions="actions"
:theme="synthesizedTheme"
@input="handleRangePanelInput"
@blur="handlePanelBlur"
@close="closeCalendar"
/>
<datetimerange-panel
@ -92,6 +101,7 @@
:theme="synthesizedTheme"
@input="handleRangePanelInput"
@close="closeCalendar"
@blur="handlePanelBlur"
/>
</div>
</div>
@ -190,7 +200,7 @@ export default {
},
default: 'date'
},
splitor: {
seperator: {
type: String,
default: 'to'
},
@ -220,8 +230,7 @@ export default {
displayTime: '',
displayStartTime: '',
displayEndTime: '',
active: false,
isFocus: false
active: false
}
},
computed: {
@ -261,15 +270,32 @@ export default {
* If new value is valid, set calendarTime and refresh display strings.
* If new value is invalid, do nothing.
*/
value (newValue) {
console.log(newValue)
value (newValue, oldValue) {
this.refresh(newValue)
if (this.isRange) {
if (!(
Array.isArray(newValue) &&
Array.isArray(oldValue) &&
newValue.length === 2 &&
newValue.length === oldValue.length &&
newValue[0] === oldValue[0] &&
newValue[1] === oldValue[1]
)) {
this.$emit('change', newValue)
}
} else { this.$emit('change', newValue) }
}
},
created () {
this.refresh(this.value)
},
methods: {
/**
* this blur is not really blur event, its key tab out of panel
*/
handlePanelBlur () {
this.closeCalendar(true)
},
handleClickOutside (e) {
if (this.active && !this.$refs.activator.contains(e.target)) {
this.closeCalendar()
@ -315,19 +341,26 @@ export default {
/**
* Blur
*/
handleTimeInputBlur () {
afterBlur (e) {
if (this.active) {
window.setTimeout(() => {
if (!(this.$refs.panel && this.$refs.panel.$el.contains(document.activeElement))) {
this.closeCalendar()
}
}, 0)
}
},
handleTimeInputBlur (e) {
if (this.disabled) return
const newSelectedDateTime = strictParse(this.displayTime, this.computedFormat, new Date())
console.log('handle blur', this.displayTime, this.computedFormat, new Date())
console.log('handle blur new time', typeof newSelectedDateTime)
if (isValid(newSelectedDateTime)) {
this.$emit('input', getTime(newSelectedDateTime))
} else {
this.refreshDisplayTime(this.value)
}
this.isFocus = false
this.afterBlur(e)
},
handleRangeInputBlur () {
handleRangeInputBlur (e) {
if (this.disabled) return
const startDateTime = strictParse(this.displayStartTime, this.computedFormat, new Date())
const endDateTime = strictParse(this.displayEndTime, this.computedFormat, new Date())
@ -336,28 +369,8 @@ export default {
} else {
this.changeStartEndTime(startDateTime, endDateTime)
}
this.isFocus = false
this.afterBlur(e)
},
// handleStartTimeInputBlur () {
// if (this.disabled) return
// const startMoment = strictParse(this.displayStartTime, this.computedFormat, null)
// if (startMoment !== null) {
// this.changeStartDateTime(startMoment)
// } else {
// this.refresh(this.value)
// }
// this.isFocus = false
// },
// handleEndTimeInputBlur () {
// if (this.disabled) return
// const endMoment = strictParse(this.displayStartTime, this.computedFormat, null)
// if (endMoment !== null) {
// this.changeStartDateTime(endMoment)
// } else {
// this.refresh(this.value)
// }
// this.isFocus = false
// },
/**
* Input
*/
@ -386,13 +399,6 @@ export default {
this.displayEndTime = endTime
// console.log('handleRangeInput', v, newStartTime, newEndTime)
},
// handleEndTimeInput (e) {
// const v = e.target.value
// const newEndTime = moment(v, this.computedFormat, true)
// if (newEndTime.isValid()) {
// this.changeEndDateTime(newEndTime)
// }
// },
/**
* Click
*/
@ -411,7 +417,7 @@ export default {
*/
handleFocus () {
if (this.disabled) return
this.isFocus = true
if (!this.active) this.openCalendar()
},
/**
* Calendar
@ -419,11 +425,18 @@ export default {
openCalendar (e) {
if (this.disabled || this.active) return
this.active = true
// console.log('into open calendar')
this.$nextTick().then(this.updatePosition)
},
closeCalendar () {
this.active = false
closeCalendar (returnFocus = false) {
if (this.active) {
this.active = false
this.$emit('blur', this.value)
if (returnFocus) {
if (this.$refs.input && this.$refs.input.$el) {
this.$refs.input.$el.focus()
}
}
}
},
toggleCalendar () {

View File

@ -1,4 +1,5 @@
import clickoutside from '../../../../directives/clickoutside'
import focusDetector from './focusDetector'
const TIME_CONST = {
weekdays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
@ -11,6 +12,9 @@ export default {
directives: {
clickoutside
},
components: {
focusDetector
},
data () {
return {
noTransition: false,
@ -21,6 +25,9 @@ export default {
clearValue () {
this.$emit('input', null)
},
handleBlur (e) {
this.$emit('blur', e)
},
banTransitionOneTick () {
if (this.active) {
this.noTransition = true

View File

@ -3,6 +3,7 @@
<div
v-if="active"
ref="self"
tabindex="0"
class="n-date-picker-panel"
:class="{
[`n-${theme}-theme`]: theme
@ -92,6 +93,7 @@
Confirm
</n-button>
</div>
<focus-detector @focus="handleBlur" />
</div>
</transition>
</template>

View File

@ -3,6 +3,7 @@
<div
v-if="active"
ref="self"
tabindex="0"
class="n-date-picker-panel n-date-picker-panel--daterange"
:class="{
[`n-${theme}-theme`]: theme
@ -165,6 +166,7 @@
Confirm
</n-button>
</div>
<focus-detector @focus="handleBlur" />
</div>
</transition>
</template>

View File

@ -3,6 +3,7 @@
<div
v-if="active"
ref="self"
tabindex="0"
class="n-date-picker-panel"
:class="{
[`n-${theme}-theme`]: theme
@ -109,6 +110,7 @@
Confirm
</n-button>
</div>
<focus-detector @focus="handleBlur" />
</div>
</transition>
</template>

View File

@ -3,6 +3,7 @@
<div
v-if="active"
ref="self"
tabindex="0"
class="n-date-picker-panel n-date-picker-panel--datetimerange"
:class="{
[`n-${theme}-theme`]: theme
@ -224,6 +225,7 @@
v-else
style="height: 12px"
/>
<focus-detector @focus="handleBlur" />
</div>
</transition>
</template>

View File

@ -0,0 +1,21 @@
<template>
<div
style="width: 0; height: 0;"
tabindex="0"
@focus="handleFocus"
@blur="handleBlur"
/>
</template>
<script>
export default {
methods: {
handleFocus () {
this.$emit('focus')
},
handleBlur () {
this.$emit('blur')
}
}
}
</script>

View File

@ -14,6 +14,7 @@
@include b(date-picker-panel) {
@include once {
outline: none;
@include fade-in-scale-up-transition(date-picker-panel);
margin-top: 4px;
margin-bottom: 4px;
@ -165,7 +166,9 @@
}
}
&:hover {
background-color: map-get($--date-picker-item-background-color, 'hover');
}
@include not-m(in-display-month) {
color: map-get($--date-picker-item-text-color, 'inactive');
}
@ -202,21 +205,18 @@
}
}
}
@include m(selected) {
@include once {
border-radius: 3px;
width: 24px;
margin: 8px 11px;
}
color: map-get($--date-picker-item-text-color, 'active');
background-color: map-get($--date-picker-item-background-color, 'active');
&::after {
background-color: map-get($--date-picker-item-sup-color, 'active');
}
}
}
&:hover {
background-color: map-get($--date-picker-item-background-color, 'hover');
@include m(selected) {
@include once {
border-radius: 3px;
width: 24px;
margin: 8px 11px;
}
color: map-get($--date-picker-item-text-color, 'active');
background-color: map-get($--date-picker-item-background-color, 'active');
&::after {
background-color: map-get($--date-picker-item-sup-color, 'active');
}
}
}
}

View File

@ -18,5 +18,5 @@
'active': $--primary-6
) !global;
$--date-picker-divider-color: rgba(255, 255, 255, .08) !global;
$--date-picker-box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.12) !global;
$--date-picker-box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.18) !global;
}

View File

@ -18,5 +18,5 @@
'active': $--primary-6
) !global;
$--date-picker-divider-color: $--n-divider-color !global;
$--date-picker-box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.12) !global;
$--date-picker-box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.18) !global;
}