mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 06:20:21 +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>
|
||||
|
||||
<div class="d-flex justify-end align-center w-100 header-sm">
|
||||
<img
|
||||
<!-- <img
|
||||
class="search-icon"
|
||||
:src="require('@/plugins/app/_img/icons/search.svg')"
|
||||
alt="search-icon"
|
||||
@@ -21,7 +21,16 @@
|
||||
placeholder="Search"
|
||||
@click="$router.push({ name: '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>
|
||||
<template v-slot:activator="{ props }">
|
||||
@@ -97,6 +106,7 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import AHeaderSearch from './a-header-search.vue';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@@ -109,6 +119,10 @@ export default {
|
||||
...mapGetters('auth', ['user']),
|
||||
},
|
||||
|
||||
components: {
|
||||
AHeaderSearch,
|
||||
},
|
||||
|
||||
methods: {
|
||||
async logOut() {
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user