mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 14:29:34 +00:00
feat(header): replace search icon with AHeaderSearch component for improved UX
This commit is contained in:
1 parent
ff1b773167
commit
3cd74cd304
2 files changed
+170
-2
No files matched your search
@@ -0,0 +1,154 @@
|
|||||||
|
<template>
|
||||||
|
<div class="header-search" :class="{ 'header-search--focused': isFocused }">
|
||||||
|
<img :src="require('@/plugins/app/_img/icons/search.svg')" />
|
||||||
|
|
||||||
|
<input
|
||||||
|
id="header-search-input"
|
||||||
|
v-model="searchValue"
|
||||||
|
type="text"
|
||||||
|
placeholder="Vyhľadávať"
|
||||||
|
@focus="handleFocus"
|
||||||
|
@blur="handleBlur"
|
||||||
|
@click="navigateToSearch"
|
||||||
|
@keydown.enter="handleSubmit"
|
||||||
|
/>
|
||||||
|
<v-btn class="header-search__close" @mousedown.prevent="handleClose">
|
||||||
|
<v-icon icon="mdi-close" size="large" />
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AHeaderSearch',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
isFocused: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
emits: ['update:modelValue', 'focus', 'blur', 'submit', 'close'],
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
searchValue: {
|
||||||
|
get() {
|
||||||
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:modelValue', value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleFocus() {
|
||||||
|
this.$emit('focus');
|
||||||
|
},
|
||||||
|
|
||||||
|
handleBlur() {
|
||||||
|
this.$emit('blur');
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClose() {
|
||||||
|
this.$emit('close');
|
||||||
|
},
|
||||||
|
|
||||||
|
navigateToSearch() {
|
||||||
|
// If already on search page, just ensure focus
|
||||||
|
if (this.$route.name === 'Search') {
|
||||||
|
this.$emit('focus');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$router.push({ name: 'Search' });
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSubmit() {
|
||||||
|
this.$emit('submit', this.searchValue);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="sass" scoped>
|
||||||
|
$breakpoint-sm: 991px
|
||||||
|
|
||||||
|
.header-search
|
||||||
|
position: relative
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
border: 1px solid #e0e0e0
|
||||||
|
border-radius: 6px
|
||||||
|
transition: all 0.3s ease-in-out
|
||||||
|
width: auto
|
||||||
|
flex-shrink: 1
|
||||||
|
flex-grow: 1
|
||||||
|
min-width: 0
|
||||||
|
max-width: 340px
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-sm)
|
||||||
|
flex-grow: 1
|
||||||
|
width: 100%
|
||||||
|
max-width: 100%
|
||||||
|
|
||||||
|
&--focused
|
||||||
|
@media (max-width: $breakpoint-sm)
|
||||||
|
flex-grow: 999
|
||||||
|
flex-shrink: 0
|
||||||
|
width: 100%
|
||||||
|
max-width: 100%
|
||||||
|
|
||||||
|
.header-search__close
|
||||||
|
opacity: 0.8
|
||||||
|
pointer-events: auto
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
opacity: 1
|
||||||
|
|
||||||
|
input
|
||||||
|
outline: none
|
||||||
|
padding: 12px 12px 12px 43px
|
||||||
|
border-right: 6px
|
||||||
|
border-left: 6px
|
||||||
|
width: 100%
|
||||||
|
min-width: 0
|
||||||
|
border: none
|
||||||
|
border-radius: 6px
|
||||||
|
|
||||||
|
img
|
||||||
|
padding: 6px
|
||||||
|
position: absolute
|
||||||
|
height: 31px
|
||||||
|
left: 8px
|
||||||
|
top: 50%
|
||||||
|
transform: translateY(-50%)
|
||||||
|
bottom: 0
|
||||||
|
user-select: none
|
||||||
|
pointer-events: none
|
||||||
|
|
||||||
|
&__close
|
||||||
|
position: absolute
|
||||||
|
opacity: 0
|
||||||
|
right: 8px
|
||||||
|
top: 50%
|
||||||
|
transform: translateY(-50%)
|
||||||
|
cursor: pointer
|
||||||
|
user-select: none
|
||||||
|
pointer-events: none
|
||||||
|
transition: opacity 0.3s ease-in-out
|
||||||
|
color: var(--color-primary)
|
||||||
|
font-size: 14px
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
--v-btn-height: 34px
|
||||||
|
--v-btn-min-height: 34px
|
||||||
|
width: 34px
|
||||||
|
min-width: 34px
|
||||||
|
|
||||||
|
border-radius: 100%
|
||||||
|
</style>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<h1>{{ $route.meta.title }}</h1>
|
<h1>{{ $route.meta.title }}</h1>
|
||||||
|
|
||||||
<div class="d-flex justify-end align-center w-100 header-sm">
|
<div class="d-flex justify-end align-center w-100 header-sm">
|
||||||
<img
|
<!-- <img
|
||||||
class="search-icon"
|
class="search-icon"
|
||||||
:src="require('@/plugins/app/_img/icons/search.svg')"
|
:src="require('@/plugins/app/_img/icons/search.svg')"
|
||||||
alt="search-icon"
|
alt="search-icon"
|
||||||
@@ -21,7 +21,16 @@
|
|||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
@click="$router.push({ name: 'Search' })"
|
@click="$router.push({ name: 'Search' })"
|
||||||
@keydown.enter="$events.emit('onSearch', search)"
|
@keydown.enter="$events.emit('onSearch', search)"
|
||||||
/>
|
/> -->
|
||||||
|
<div style="margin-right: 16px">
|
||||||
|
<A-header-search
|
||||||
|
v-model="search"
|
||||||
|
@focus="$router.push({ name: 'Search' })"
|
||||||
|
@blur="() => ({})"
|
||||||
|
@submit="$events.emit('onSearch', search)"
|
||||||
|
@close="() => ({})"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<v-menu>
|
<v-menu>
|
||||||
<template v-slot:activator="{ props }">
|
<template v-slot:activator="{ props }">
|
||||||
@@ -97,6 +106,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
|
import AHeaderSearch from './a-header-search.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@@ -109,6 +119,10 @@ export default {
|
|||||||
...mapGetters('auth', ['user']),
|
...mapGetters('auth', ['user']),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
AHeaderSearch,
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async logOut() {
|
async logOut() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in new issue
Block a user