feat: added mobile search styles

This commit is contained in:
Rewrite0
2024-09-23 11:54:39 +08:00
parent 5092c7f093
commit 9aadcfd122
6 changed files with 160 additions and 108 deletions

View File

@@ -69,41 +69,43 @@ defineEmits(['click']);
<template v-else-if="type === 'search'">
<div
w-480
max-w-90vw
rounded-12
p-4
shadow
bg="#eee5f4"
transition="opacity ease-in-out duration-300"
>
<div bg-white rounded-8 p-12 fx-cer justify-between gap-x-16>
<div w-400 gap-x-16 fx-cer>
<div w-72 rounded-6 overflow-hidden>
<ab-image
:src="bangumi.poster_link"
:aspect-ratio="72 / 44"
w-full
></ab-image>
<div w-full bg-white rounded-8 p-12 flex gap-x-14>
<div w-72 rounded-6 overflow-hidden>
<ab-image :src="bangumi.poster_link" w-full></ab-image>
</div>
<div flex="~ col 1 gap-y-4 justify-between">
<div text="h3 primary">
{{ bangumi.official_title }}
</div>
<div flex="~ col gap-y-4">
<div w-300 text="h3 primary" truncate>
{{ bangumi.official_title }}
</div>
<div flex="~ gap-x-8">
<template
v-for="i in ['season', 'group_name', 'subtitle']"
:key="i"
>
<ab-tag
v-if="bangumi[i]"
:title="i === 'season' ? `Season ${bangumi[i]}` : bangumi[i]"
type="primary"
/>
</template>
</div>
<div flex="~ wrap gap-8">
<template
v-for="i in ['season', 'group_name', 'subtitle']"
:key="i"
>
<ab-tag
v-if="bangumi[i]"
:title="i === 'season' ? `Season ${bangumi[i]}` : bangumi[i]"
type="primary"
/>
</template>
</div>
</div>
<ab-add :round="true" type="medium" @click="() => $emit('click')" />
<ab-add
my-auto
:round="true"
type="medium"
@click="() => $emit('click')"
/>
</div>
</div>
</template>

View File

@@ -15,7 +15,7 @@ withDefaults(
bg-theme-row
w-full
text-white
px-20
px="10 pc:20"
h="38 pc:45"
fx-cer
justify-between

View File

@@ -20,7 +20,7 @@ withDefaults(
w-full
text-white
fx-cer
px-20
px="10 pc:20"
h="38 pc:45"
justify-between
>

View File

@@ -1,12 +1,18 @@
<script lang="ts" setup>
import {
Popover,
PopoverButton,
PopoverOverlay,
PopoverPanel,
} from '@headlessui/vue';
import { vOnClickOutside } from '@vueuse/components';
import { Search } from '@icon-park/vue-next';
import type { BangumiRule } from '#/bangumi';
defineEmits<{
(e: 'add-bangumi', bangumiRule: BangumiRule): void;
}>();
const showProvider = ref(false);
const { providers, provider, loading, inputValue, bangumiList } = storeToRefs(
useSearchStore()
);
@@ -15,59 +21,82 @@ const { getProviders, onSearch, clearSearch } = useSearchStore();
onMounted(() => {
getProviders();
});
function onSelect(site: string) {
provider.value = site;
showProvider.value = false;
}
</script>
<template>
<ab-search
v-model:inputValue="inputValue"
:provider="provider"
:loading="loading"
@search="onSearch"
@select="() => (showProvider = !showProvider)"
/>
<Popover v-bind="$attrs">
<transition name="fade">
<PopoverOverlay
class="fixed top-0 left-0 w-full h-full bg-black bg-opacity-50 z-5"
/>
</transition>
<div
v-show="showProvider"
v-on-click-outside="() => (showProvider = false)"
abs
top-84
left-540
w-100
rounded-12
shadow
bg-white
z-99
overflow-hidden
>
<div
v-for="site in providers"
:key="site"
hover:bg-theme-row
is-btn
@click="() => onSelect(site)"
<PopoverButton bg-transparent text="pc:24 20" is-btn btn-click>
<Search size="1em" fill="#fff" />
</PopoverButton>
<transition
enter-active-class="transition duration-200 ease-out"
enter-from-class="translate-y--20 opacity-0"
enter-to-class="translate-y-0 opacity-100"
leave-active-class="transition duration-150 ease-in"
leave-from-class="translate-y-0 opacity-100"
leave-to-class="translate-y--20 opacity-0"
>
<div text="h3 primary" hover="text-white" p-12 truncate>
{{ site }}
</div>
</div>
</div>
<div v-on-click-outside="clearSearch" abs top-84 left-192 z-8>
<transition-group name="fade-list" tag="ul" space-y-12>
<li v-for="bangumi in bangumiList" :key="bangumi.order">
<ab-bangumi-card
:bangumi="bangumi.value"
type="search"
@click="() => $emit('add-bangumi', bangumi.value)"
<PopoverPanel
v-on-click-outside="clearSearch"
class="search-panel"
fixed
left-0
right-0
m-auto
w-max
z-5
>
<ab-search
v-model:inputValue="inputValue"
v-model:provider="provider"
:providers="providers"
:loading="loading"
@search="onSearch"
/>
</li>
</transition-group>
</div>
<div class="search-list" space-y-10 overflow-auto>
<transition-group name="fade-list">
<template v-for="bangumi in bangumiList" :key="bangumi.order">
<ab-bangumi-card
:bangumi="bangumi.value"
type="search"
@click="() => $emit('add-bangumi', bangumi.value)"
/>
</template>
</transition-group>
</div>
</PopoverPanel>
</transition>
</Popover>
</template>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.search-panel {
--_offset-top: 80px;
--_offset-bottom: 40px;
--_search-input-height: 36px;
--_search-list-offset: 20px;
@include forMobile {
--_offset-top: 65px;
--_search-list-offset: 10px;
}
top: var(--_offset-top);
.search-list {
margin-top: var(--_search-list-offset);
max-height: calc(
100vh - var(--_offset-top) - var(--_offset-bottom) -
var(--_search-input-height) - var(--_search-list-offset)
);
}
}
</style>

View File

@@ -1,26 +1,28 @@
<script lang="ts" setup>
import { Down, Search } from '@icon-park/vue-next';
import { NSpin } from 'naive-ui';
import { watch } from 'vue';
withDefaults(
defineProps<{
provider: string;
providers: string[];
loading: boolean;
}>(),
{
provider: '',
loading: false,
}
);
defineEmits(['select', 'search']);
defineEmits(['search']);
const provider = defineModel<string>('provider');
const inputValue = defineModel<string>('inputValue');
watch(inputValue, (val) => {
console.log(val);
});
const showProvider = ref(false);
function onSelect(site: string) {
provider.value = site;
showProvider.value = false;
}
</script>
<template>
@@ -33,7 +35,7 @@ watch(inputValue, (val) => {
pl-12
gap-x-12
w-400
overflow-hidden
max-w-90vw
shadow-inner
>
<Search
@@ -54,22 +56,45 @@ watch(inputValue, (val) => {
input-reset
@keyup.enter="$emit('search')"
/>
<div
h-full
f-cer
justify-between
px-12
w-100
class="provider"
is-btn
@click="$emit('select')"
>
<div text-h3 truncate>
{{ provider }}
</div>
<div class="provider">
<div rel w-100 h-full px-12 rounded-inherit class="provider" is-btn>
<div
fx-cer
wh-full
justify-between
@click="() => (showProvider = !showProvider)"
>
<div text-h3 truncate>
{{ provider }}
</div>
<Down />
</div>
<div
v-show="showProvider"
abs
top="100%"
left-0
w-100
rounded-12
shadow
bg-white
z-1
overflow-hidden
>
<div
v-for="site in providers"
:key="site"
hover:bg-theme-row
is-btn
@click="() => onSelect(site)"
>
<div text="h3 primary" hover="text-white" p-12 truncate>
{{ site }}
</div>
</div>
</div>
</div>
</div>
</template>

View File

@@ -114,13 +114,11 @@ onUnmounted(() => {
pc:top-2
/>
</div>
<div hidden pc:block>
<ab-search-bar @add-bangumi="addSearchResult" />
</div>
</div>
<div ml-auto>
<div ml-auto fx-cer>
<ab-search-bar mr="pc:16 10" fx-cer @add-bangumi="addSearchResult" />
<ab-status-bar
:items="items"
:running="running"
@@ -128,10 +126,8 @@ onUnmounted(() => {
@change-lang="changeLocale"
/>
</div>
<ab-change-account v-model:show="showAccount"></ab-change-account>
<ab-add-rss
v-model:show="showAddRSS"
v-model:rule="searchRule"
></ab-add-rss>
</div>
<ab-change-account v-model:show="showAccount"></ab-change-account>
<ab-add-rss v-model:show="showAddRSS" v-model:rule="searchRule"></ab-add-rss>
</template>