Code Refactoring

Removed multiple else if with Switch, for better readability and perfomance
This commit is contained in:
Edison Augusthy
2019-09-30 11:29:58 +05:30
committed by GitHub
parent 0afd0205ed
commit 2d321bc27d

View File

@@ -1,181 +1,207 @@
<template> <template>
<div class="autocomplete-wrapper"> <div class="autocomplete-wrapper">
<label> <label>
<input type="text" :placeholder="placeholder" v-model="value" @input="updateSuggestions" @keyup="updateSuggestions" @click="updateSuggestions" @keydown="handleKeystroke" ref="acInput" :spellcheck="spellcheck" :autocapitalize="spellcheck" :autocorrect="spellcheck"> <input
<ul class="suggestions" v-if="suggestions.length > 0 && suggestionsVisible" :style="{ transform: `translate(${suggestionsOffsetLeft}px, 0)` }"> type="text"
<li v-for="(suggestion, index) in suggestions" @click.prevent="forceSuggestion(suggestion)" :class="{ active: currentSuggestionIndex === index }" :key="index">{{ suggestion }}</li> :placeholder="placeholder"
v-model="value"
@input="updateSuggestions"
@keyup="updateSuggestions"
@click="updateSuggestions"
@keydown="handleKeystroke"
ref="acInput"
:spellcheck="spellcheck"
:autocapitalize="spellcheck"
:autocorrect="spellcheck"
/>
<ul
class="suggestions"
v-if="suggestions.length > 0 && suggestionsVisible"
:style="{ transform: `translate(${suggestionsOffsetLeft}px, 0)` }"
>
<li
v-for="(suggestion, index) in suggestions"
@click.prevent="forceSuggestion(suggestion)"
:class="{ active: currentSuggestionIndex === index }"
:key="index"
>{{ suggestion }}</li>
</ul> </ul>
</label> </label>
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.autocomplete-wrapper { .autocomplete-wrapper {
position: relative; position: relative;
input:focus+ul.suggestions, input:focus + ul.suggestions,
ul.suggestions:hover { ul.suggestions:hover {
display: block;
}
ul.suggestions {
display: none;
background-color: var(--atc-color);
position: absolute;
top: 90%;
margin: 0 4px;
left: 0;
padding: 0;
border-radius: 0 0 4px 4px;
z-index: 9999;
transition: transform 200ms ease-out;
li {
width: 100%;
display: block; display: block;
} padding: 8px 16px;
font-weight: 700;
font-size: 18px;
font-family: monospace;
white-space: pre-wrap;
ul.suggestions { &:last-child {
display: none; border-radius: 0 0 4px 4px;
background-color: var(--atc-color); }
position: absolute;
top: 90%;
margin: 0 4px;
left: 0;
padding: 0;
border-radius: 0 0 4px 4px;
z-index: 9999;
transition: transform 200ms ease-out;
li { &:hover,
width: 100%; &.active {
display: block; background-color: var(--ac-color);
padding: 8px 16px; color: var(--act-color);
font-weight: 700; cursor: pointer;
font-size: 18px;
font-family: monospace;
white-space: pre-wrap;
&:last-child {
border-radius: 0 0 4px 4px;
}
&:hover,
&.active {
background-color: var(--ac-color);
color: var(--act-color);
cursor: pointer;
}
} }
} }
} }
}
</style> </style>
<script> <script>
const KEY_TAB = 9; const KEY_TAB = 9;
const KEY_ESC = 27; const KEY_ESC = 27;
const KEY_ARROW_UP = 38; const KEY_ARROW_UP = 38;
const KEY_ARROW_DOWN = 40; const KEY_ARROW_DOWN = 40;
export default { export default {
props: { props: {
spellcheck: { spellcheck: {
type: Boolean, type: Boolean,
default: true, default: true,
required: false required: false
},
placeholder: {
type: String,
default: 'Start typing...',
required: false
},
source: {
type: Array,
required: true
}
}, },
watch: { placeholder: {
value() { type: String,
this.$emit('input', this.value); default: "Start typing...",
} required: false
}, },
data() { source: {
return { type: Array,
value: "application/json", required: true
selectionStart: 0, }
suggestionsOffsetLeft: 0, },
currentSuggestionIndex: -1,
suggestionsVisible: false
}
},
methods: { watch: {
updateSuggestions(event) { value() {
// Hide suggestions if ESC pressed. this.$emit("input", this.value);
if (event.which && event.which === KEY_ESC) { }
event.preventDefault(); },
this.suggestionsVisible = false;
this.currentSuggestionIndex = -1;
return;
}
// As suggestions is a reactive property, this implicitly data() {
// causes suggestions to update. return {
this.selectionStart = this.$refs.acInput.selectionStart; value: "application/json",
this.suggestionsOffsetLeft = (12 * this.selectionStart); selectionStart: 0,
this.suggestionsVisible = true; suggestionsOffsetLeft: 0,
}, currentSuggestionIndex: -1,
suggestionsVisible: false
};
},
forceSuggestion(text) { methods: {
let input = this.value.substring(0, this.selectionStart); updateSuggestions(event) {
this.value = input + text; // Hide suggestions if ESC pressed.
if (event.which && event.which === KEY_ESC) {
this.selectionStart = this.value.length; event.preventDefault();
this.suggestionsVisible = true; this.suggestionsVisible = false;
this.currentSuggestionIndex = -1; this.currentSuggestionIndex = -1;
}, return;
}
handleKeystroke(event) { // As suggestions is a reactive property, this implicitly
if (event.which === KEY_ARROW_UP) { // causes suggestions to update.
this.selectionStart = this.$refs.acInput.selectionStart;
this.suggestionsOffsetLeft = 12 * this.selectionStart;
this.suggestionsVisible = true;
},
forceSuggestion(text) {
let input = this.value.substring(0, this.selectionStart);
this.value = input + text;
this.selectionStart = this.value.length;
this.suggestionsVisible = true;
this.currentSuggestionIndex = -1;
},
handleKeystroke(event) {
switch (event.which) {
case KEY_ARROW_UP:
event.preventDefault(); event.preventDefault();
this.currentSuggestionIndex =this.currentSuggestionIndex - 1 >= 0 ? this.currentSuggestionIndex - 1 : 0;
break;
this.currentSuggestionIndex = this.currentSuggestionIndex - 1 >= 0 ? case KEY_ARROW_DOWN:
this.currentSuggestionIndex - 1 :
0;
} else if (event.which === KEY_ARROW_DOWN) {
event.preventDefault(); event.preventDefault();
this.currentSuggestionIndex = this.currentSuggestionIndex < this.suggestions.length - 1 ? this.currentSuggestionIndex + 1
: this.suggestions.length - 1;
break;
this.currentSuggestionIndex = this.currentSuggestionIndex < this.suggestions.length - 1 ? case KEY_TAB:
this.currentSuggestionIndex + 1 :
this.suggestions.length - 1;
}
if (event.which === KEY_TAB) {
event.preventDefault(); event.preventDefault();
let activeSuggestion = this.suggestions[this.currentSuggestionIndex >= 0 ? this.currentSuggestionIndex : 0]; let activeSuggestion = this.suggestions[this.currentSuggestionIndex >= 0 ? this.currentSuggestionIndex : 0];
if (activeSuggestion) { if (activeSuggestion) {
let input = this.value.substring(0, this.selectionStart); let input = this.value.substring(0, this.selectionStart);
this.value = input + activeSuggestion; this.value = input + activeSuggestion;
} }
} break;
default:
break;
} }
}, }
},
computed: { computed: {
/** /**
* Gets the suggestions list to be displayed under the input box. * Gets the suggestions list to be displayed under the input box.
* *
* @returns {default.props.source|{type, required}} * @returns {default.props.source|{type, required}}
*/ */
suggestions() { suggestions() {
let input = this.value.substring(0, this.selectionStart); let input = this.value.substring(0, this.selectionStart);
return this.source.filter((entry) => { return (
return entry.toLowerCase().startsWith(input.toLowerCase()) && this.source
input.toLowerCase() !== entry.toLowerCase(); .filter(entry => {
return (
entry.toLowerCase().startsWith(input.toLowerCase()) &&
input.toLowerCase() !== entry.toLowerCase()
);
}) })
// Cut off the part that's already been typed. // Cut off the part that's already been typed.
.map((entry) => entry.substring(this.selectionStart)) .map(entry => entry.substring(this.selectionStart))
// We only want the top 3 suggestions. // We only want the top 3 suggestions.
.slice(0, 3); .slice(0, 3)
} );
},
mounted() {
this.updateSuggestions({
target: this.$refs.acInput
});
} }
} },
mounted() {
this.updateSuggestions({
target: this.$refs.acInput
});
}
};
</script> </script>