Skip to content

Commit

Permalink
Add: [Client] スマホ縦画面向け検索ボックスを実装
Browse files Browse the repository at this point in the history
ほぼ LLM に丸投げでいい感じになった ありがてえ〜
  • Loading branch information
tsukumijima committed Aug 24, 2024
1 parent 1fcc764 commit e068fe8
Showing 1 changed file with 105 additions and 11 deletions.
116 changes: 105 additions & 11 deletions client/src/components/SPHeaderBar.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,74 @@
<template>
<header class="header">
<router-link v-ripple class="konomitv-logo" to="/tv/">
<img class="konomitv-logo__image" src="/assets/images/logo.svg" height="21">
</router-link>
<v-spacer></v-spacer>
<div v-ripple class="search-button" @click="Message.warning('検索機能は現在開発中です。')">
<Icon icon="fluent:search-20-filled" height="24px" />
</div>
<header class="header" :class="{ 'search-active': is_search_active }">
<template v-if="!is_search_active">
<router-link v-ripple class="konomitv-logo" to="/tv/">
<img class="konomitv-logo__image" src="/assets/images/logo.svg" height="21">
</router-link>
<v-spacer></v-spacer>
<div v-ripple class="search-button" @click="activateSearch">
<Icon icon="fluent:search-20-filled" height="24px" />
</div>
</template>
<template v-else>
<div class="search-box">
<input ref="search_input" type="text" :placeholder="search_placeholder"
v-model="search_query" @keydown="handleKeyDown">
<div v-ripple class="search-box__close" @click="deactivateSearch">
<Icon icon="fluent:dismiss-20-filled" height="24px" />
</div>
</div>
</template>
</header>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue';
import { useRouter, useRoute } from 'vue-router';
const router = useRouter();
const route = useRoute();
const is_search_active = ref(false);
const search_query = ref('');
const search_input = ref<HTMLInputElement | null>(null);
const search_placeholder = computed(() => {
return route.path.startsWith('/videos')
? '録画番組を検索...'
: '放送予定の番組を検索...';
});
import Message from '@/message';
const getSearchPath = () => {
return route.path.startsWith('/videos')
? '/videos/search'
: '/tv/search';
};
const activateSearch = () => {
is_search_active.value = true;
// 次のティックで入力フォーカスを設定
setTimeout(() => {
search_input.value?.focus();
}, 0);
};
const deactivateSearch = () => {
is_search_active.value = false;
search_query.value = '';
};
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Enter' && !event.isComposing) {
if (search_query.value.trim()) {
const search_path = getSearchPath();
router.push(`${search_path}?query=${encodeURIComponent(search_query.value.trim())}`);
}
} else if (event.key === 'Escape') {
deactivateSearch();
}
};
</script>
<style lang="scss" scoped>

<style lang="scss" scoped>
.header {
display: none;
justify-content: center;
Expand All @@ -29,6 +82,10 @@ import Message from '@/message';
display: flex;
}
&.search-active {
padding: 0;
}
.konomitv-logo {
display: block;
padding: 12px 8px;
Expand All @@ -47,7 +104,44 @@ import Message from '@/message';
margin-right: -2px;
padding: 2px;
border-radius: 8px;
cursor: pointer;
}
}
.search-box {
display: flex;
align-items: center;
width: 100%;
height: 100%;
padding: 0 16px;
padding-top: 14px;
input {
flex-grow: 1;
height: 100%;
border: none;
background: transparent;
color: rgb(var(--v-theme-text));
font-size: 16px;
&:focus {
outline: none;
}
&::placeholder {
color: rgb(var(--v-theme-text-darken-2));
}
}
&__close {
display: flex;
align-items: center;
justify-content: center;
position: relative;
margin-right: -2px;
padding: 2px;
border-radius: 8px;
cursor: pointer;
}
}
}
</style>

0 comments on commit e068fe8

Please sign in to comment.