mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-18 12:34:25 +08:00
feat(date-picker): change & blur events & some keyboard bindings
This commit is contained in:
parent
ad240f2b3f
commit
ad76b5736e
76
demo/documentation/components/datePicker/enUS/events.md
Normal file
76
demo/documentation/components/datePicker/enUS/events.md
Normal 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;
|
||||
}
|
||||
```
|
@ -6,4 +6,5 @@ daterange
|
||||
datetimerange
|
||||
disabled
|
||||
actions
|
||||
events
|
||||
```
|
@ -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 () {
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
21
packages/common/DatePicker/src/panel/focusDetector.vue
Normal file
21
packages/common/DatePicker/src/panel/focusDetector.vue
Normal 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>
|
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user