1
1
mirror of https://github.com/aelve/guide.git synced 2024-11-22 03:12:58 +03:00

Search shortcut

This commit is contained in:
avele 2019-11-28 00:37:29 +04:00
parent 082bfb01a6
commit af29bcf79d
2 changed files with 67 additions and 6 deletions

View File

@ -2,6 +2,7 @@
<v-form
class="search-bar"
@keydown.enter.native.prevent="processSearchQuery"
@keydown.esc.native.prevent="blur"
>
<v-text-field
solo
@ -28,6 +29,12 @@
v-show="searchQuery"
@click="clear"
>$vuetify.icons.times</v-icon>
<span
slot="append"
class="search-bar__input__shortcut-tip"
v-show="!isFocused"
@click="clear"
>/</span>
</v-text-field>
</v-form>
</template>
@ -35,13 +42,42 @@
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
import isEventTypingOrDialog from 'client/helpers/isEventTypingOrDialog'
@Component
export default class SearchBar extends Vue {
shortcutListener
isFocused = false
searchQuery = this.$store.state.wiki.searchQuery
get inputIconsColor () {
return this.isFocused ? '#717171' : 'rgba(255, 255, 255, 0.7)'
}
mounted () {
this.addShortcutListener()
}
beforeDestroy () {
this.removeShortcutListener()
}
addShortcutListener () {
this.shortcutListener = document.addEventListener('keydown', event => {
const { keyCode } = event
const slashButtonCode = 191
if (keyCode !== slashButtonCode || this.isFocused || isEventTypingOrDialog(event)) {
return
}
event.preventDefault()
this.focus()
})
}
removeShortcutListener () {
document.removeEventListener('keydown', this.shortcutListener)
}
processSearchQuery () {
const searchResultsRouteName = 'SearchResults'
const isSearchCurrentRoute = this.$route.name === searchResultsRouteName
@ -53,10 +89,6 @@ export default class SearchBar extends Vue {
this.$router.push({ name: searchResultsRouteName, query: { query: this.searchQuery } })
}
get inputIconsColor () {
return this.isFocused ? '#717171' : 'rgba(255, 255, 255, 0.7)'
}
clear () {
this.searchQuery = ''
}
@ -64,6 +96,12 @@ export default class SearchBar extends Vue {
focus () {
this.$refs.input.focus()
}
blur () {
if (this.isFocused) {
this.$refs.input.blur()
}
}
}
</script>
@ -96,9 +134,22 @@ export default class SearchBar extends Vue {
.search-bar__input__clear-btn {
cursor: pointer;
}
.search-bar__input__shortcut-tip {
color: rgba(255, 255, 255, 0.3);
font-size: 0.6rem;
border: rgba(255, 255, 255, 0.3) solid 1px;
border-radius: 3px;
line-height: 0.3rem;
padding: 0.4rem;
}
@media screen and (min-width: 780px) {
.search-bar__input__clear-btn {
display: none;
}
}
@media screen and (max-width: 780px) {
.search-bar__input__shortcut-tip {
display: none;
}
}
</style>

View File

@ -0,0 +1,10 @@
export default function (event) {
const { target } = event
const dialogSelector = '.v-dialog__content'
const isDialog = target.classList.contains(dialogSelector) || target.closest(dialogSelector)
const nodeName = target.nodeName.toLowerCase()
const typingElements = ['input', 'textarea']
const isTypingElement = typingElements.includes(nodeName)
return isDialog || isTypingElement
}