mirror of
https://github.com/Hopiu/vue-material.git
synced 2026-04-29 02:54:48 +00:00
Add keyboard shortcuts to select
This commit is contained in:
parent
dca1629304
commit
caeb7f5241
7 changed files with 80 additions and 66 deletions
|
|
@ -16,6 +16,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"autosize": "^3.0.17",
|
||||
"element.scrollintoviewifneeded-polyfill": "^1.0.1",
|
||||
"scopedQuerySelectorShim": "github:lazd/scopedQuerySelectorShim"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
<template>
|
||||
<div class="md-option" @click="selectOption" v-md-ink-ripple>
|
||||
<div
|
||||
class="md-option"
|
||||
:class="classes"
|
||||
@click="selectOption"
|
||||
@mouseenter="setHighlight"
|
||||
@keydown.enter="selectOption"
|
||||
v-md-ink-ripple
|
||||
tabindex="-1">
|
||||
<span>
|
||||
<slot></slot>
|
||||
</span>
|
||||
|
|
@ -7,6 +14,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import 'element.scrollintoviewifneeded-polyfill';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: [String, Boolean, Number]
|
||||
|
|
@ -16,19 +25,42 @@
|
|||
index: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
classes() {
|
||||
return {
|
||||
'md-highlighted': this.hasHighlight()
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
classes() {
|
||||
if (this.hasHighlight()) {
|
||||
this.$el.focus();
|
||||
this.$el.scrollIntoViewIfNeeded(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setHighlight() {
|
||||
this.$parent.highlightOption(this.index);
|
||||
},
|
||||
hasHighlight() {
|
||||
return this.index === this.$parent.highlighted;
|
||||
},
|
||||
selectOption() {
|
||||
if (this.$parent.$el.classList.contains('md-select')) {
|
||||
this.$parent.selectOption(this.value);
|
||||
} else {
|
||||
this.$parent.$parent.selectOption(this.value);
|
||||
if (this.hasHighlight()) {
|
||||
if (this.$parent.$el.classList.contains('md-select')) {
|
||||
this.$parent.selectOption(this.value);
|
||||
} else {
|
||||
this.$parent.$parent.selectOption(this.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let parentClasses = this.$parent.$el.classList;
|
||||
|
||||
if (!parentClasses.contains('md-select') && !parentClasses.contains('md-option-group')) {
|
||||
if (!parentClasses.contains('md-select')) {
|
||||
this.$destroy();
|
||||
|
||||
throw new Error('You should wrap the md-option in a md-select');
|
||||
|
|
|
|||
|
|
@ -102,6 +102,15 @@
|
|||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.md-subheader {
|
||||
color: rgba(#757575, .87);
|
||||
text-transform: uppercase;
|
||||
|
||||
&:first-child {
|
||||
margin-top: -8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.md-option {
|
||||
|
|
@ -114,13 +123,14 @@
|
|||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
transform: translate3D(0, 0, 0);
|
||||
transition: $swift-ease-out;
|
||||
font-size: 16px;
|
||||
line-height: 1.2em;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
&.md-highlighted {
|
||||
background-color: rgba(#000, .12);
|
||||
}
|
||||
|
||||
|
|
@ -130,16 +140,3 @@
|
|||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.md-option-group:first-child {
|
||||
margin-top: -8px;
|
||||
}
|
||||
|
||||
.md-option-group-label {
|
||||
padding: 16px;
|
||||
display: block;
|
||||
color: rgba(#757575, .87);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
<div
|
||||
class="md-select"
|
||||
:class="classes"
|
||||
:tabindex="disabled ? null : '0'"
|
||||
v-on-clickaway="close">
|
||||
:tabindex="disabled ? null : '0'">
|
||||
<span class="md-select-value" @click="show">{{ value }}</span>
|
||||
|
||||
<div
|
||||
|
|
@ -11,8 +10,8 @@
|
|||
tabindex="-1"
|
||||
ref="menu"
|
||||
@keydown.esc.prevent="close"
|
||||
@keydown.up.prevent="highlightOption(-1)"
|
||||
@keydown.down.prevent="highlightOption(1)">
|
||||
@keydown.up.prevent="highlightOption(highlighted - 1)"
|
||||
@keydown.down.prevent="highlightOption(highlighted + 1)">
|
||||
<div class="md-select-menu-container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
|
@ -54,16 +53,23 @@
|
|||
show() {
|
||||
this.$refs.menu.focus();
|
||||
this.active = true;
|
||||
document.addEventListener('click', this.closeOnOffClick);
|
||||
},
|
||||
close() {
|
||||
this.$refs.menu.blur();
|
||||
this.active = false;
|
||||
if (this.active) {
|
||||
this.$refs.menu.blur();
|
||||
this.active = false;
|
||||
document.removeEventListener('click', this.closeOnOffClick);
|
||||
}
|
||||
},
|
||||
closeOnOffClick(event) {
|
||||
if (!this.$el.contains(event.target)) {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
highlightOption(factor) {
|
||||
let factorAbs = Math.abs(factor);
|
||||
|
||||
if (factorAbs >= 0 && factorAbs <= this.optionsAmount) {
|
||||
this.highlighted += factor;
|
||||
if (factor >= 1 && factor <= this.optionsAmount) {
|
||||
this.highlighted = factor;
|
||||
}
|
||||
},
|
||||
selectOption(value) {
|
||||
|
|
@ -82,10 +88,13 @@
|
|||
|
||||
this.$parent.setValue(this.value);
|
||||
this.$parent.hasSelect = true;
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$parent.setValue(null);
|
||||
this.$parent.hasSelect = false;
|
||||
|
||||
document.removeEventListener('click', this.closeOnOffClick);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
<script>
|
||||
import Vue from 'vue';
|
||||
import CoreTheme from './stylesheets/core.theme';
|
||||
import clickaway from './directives/clickaway';
|
||||
|
||||
window.VueMaterial = {
|
||||
styles: [CoreTheme]
|
||||
};
|
||||
|
||||
Vue.directive('onClickaway', clickaway);
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
let handleClick;
|
||||
|
||||
export default {
|
||||
acceptStatement: true,
|
||||
priority: 700,
|
||||
update(element, handler) {
|
||||
handleClick = function(event) {
|
||||
if (!element.contains(event.target)) {
|
||||
handler.value(event);
|
||||
}
|
||||
};
|
||||
|
||||
document.documentElement.addEventListener('click', handleClick);
|
||||
},
|
||||
unbind() {
|
||||
document.documentElement.removeEventListener(document.documentElement, 'click', handleClick);
|
||||
}
|
||||
};
|
||||
|
|
@ -50,22 +50,19 @@
|
|||
<md-input-container>
|
||||
<label for="food">Food</label>
|
||||
<md-select name="food" id="food" v-model="food">
|
||||
<md-optgroup label="Fruits">
|
||||
<md-option value="Apples">Apples</md-option>
|
||||
<md-option value="Bananas">Bananas</md-option>
|
||||
<md-option value="Peaches">Peaches</md-option>
|
||||
<md-option value="Oranges">Oranges</md-option>
|
||||
</md-optgroup>
|
||||
<md-subheader>Fruits</md-subheader>
|
||||
<md-option value="Apples">Apples</md-option>
|
||||
<md-option value="Bananas">Bananas</md-option>
|
||||
<md-option value="Peaches">Peaches</md-option>
|
||||
<md-option value="Oranges">Oranges</md-option>
|
||||
|
||||
<md-optgroup label="Vegetables">
|
||||
<md-option value="Carrots">Carrots</md-option>
|
||||
<md-option value="Cucumbers">Cucumbers</md-option>
|
||||
</md-optgroup>
|
||||
<md-subheader>Vegetables</md-subheader>
|
||||
<md-option value="Carrots">Carrots</md-option>
|
||||
<md-option value="Cucumbers">Cucumbers</md-option>
|
||||
|
||||
<md-optgroup label="Baked Goods">
|
||||
<md-option value="Apple Pie">Apple Pie</md-option>
|
||||
<md-option value="Chocolate Cake">Chocolate Cake</md-option>
|
||||
</md-optgroup>
|
||||
<md-subheader>Baked Goods</md-subheader>
|
||||
<md-option value="Apple Pie">Apple Pie</md-option>
|
||||
<md-option value="Chocolate Cake">Chocolate Cake</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue