mirror of
https://github.com/Coldsmiles/infstarweb.git
synced 2026-04-23 02:30:41 +08:00
feat: add shared components for donation, facility, feature bento, filter panel, join wizard, leaderboard, player, playstyle, and town cards
- Implemented DonationCard.vue for displaying donation details. - Created FacilityCard.vue to showcase facility information with status badges. - Developed FeatureBentoCard.vue and FeatureBentoGrid.vue for feature display in a grid layout. - Added FilterPanel.vue for filtering content with search and tag options. - Introduced JoinWizard.vue for a step-by-step joining process with device and playstyle selection. - Created LeaderboardCard.vue to display leaderboard information. - Implemented PlayerCard.vue for showcasing player profiles and stats. - Developed PlaystyleCard.vue for selecting playstyle options. - Added TownCard.vue to present town details with badges and images. - Included demo data in demoData.js for testing and development purposes.
This commit is contained in:
189
src/components/layout/SiteNavbar.vue
Normal file
189
src/components/layout/SiteNavbar.vue
Normal file
@@ -0,0 +1,189 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import MobileNavDrawer from './MobileNavDrawer.vue';
|
||||
|
||||
const props = defineProps({
|
||||
items: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
activePath: {
|
||||
type: String,
|
||||
default: '/',
|
||||
},
|
||||
logoSrc: {
|
||||
type: String,
|
||||
default: 'https://img.lunadeer.cn/i/2024/04/22/6625ce6c8ddc1.png',
|
||||
},
|
||||
logoAlt: {
|
||||
type: String,
|
||||
default: '白鹿原 Minecraft 服务器 Logo',
|
||||
},
|
||||
ctaLabel: {
|
||||
type: String,
|
||||
default: '加入游戏',
|
||||
},
|
||||
ctaHref: {
|
||||
type: String,
|
||||
default: '/join',
|
||||
},
|
||||
});
|
||||
|
||||
const mobileOpen = ref(false);
|
||||
|
||||
const isActive = (href) => href === props.activePath;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header class="site-navbar">
|
||||
<div class="site-navbar__inner bl-shell">
|
||||
<button
|
||||
type="button"
|
||||
class="site-navbar__toggle"
|
||||
aria-label="打开菜单"
|
||||
@click="mobileOpen = true"
|
||||
>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
|
||||
<a class="site-navbar__logo" href="/">
|
||||
<img :src="logoSrc" :alt="logoAlt">
|
||||
</a>
|
||||
|
||||
<nav class="site-navbar__links" aria-label="主导航">
|
||||
<a
|
||||
v-for="item in items"
|
||||
:key="item.href"
|
||||
:href="item.href"
|
||||
:class="['site-navbar__link', { 'is-active': isActive(item.href) }]"
|
||||
>
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<a class="site-navbar__cta" :href="ctaHref">{{ ctaLabel }}</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<MobileNavDrawer
|
||||
:open="mobileOpen"
|
||||
:items="items"
|
||||
:cta-label="ctaLabel"
|
||||
:cta-href="ctaHref"
|
||||
@close="mobileOpen = false"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.site-navbar {
|
||||
position: fixed;
|
||||
inset: 0 0 auto;
|
||||
z-index: 1100;
|
||||
height: var(--bl-header-height);
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.site-navbar__inner {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.site-navbar__toggle {
|
||||
display: none;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: transparent;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.site-navbar__toggle span {
|
||||
width: 16px;
|
||||
height: 1.5px;
|
||||
background: var(--bl-text);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.site-navbar__logo img {
|
||||
width: auto;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.site-navbar__links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 22px;
|
||||
margin-left: auto;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.site-navbar__link {
|
||||
position: relative;
|
||||
font-size: 0.82rem;
|
||||
color: rgba(29, 29, 31, 0.82);
|
||||
text-decoration: none;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.site-navbar__link:hover,
|
||||
.site-navbar__link.is-active {
|
||||
color: var(--bl-text);
|
||||
}
|
||||
|
||||
.site-navbar__link.is-active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -12px;
|
||||
height: 2px;
|
||||
border-radius: 999px;
|
||||
background: var(--bl-text);
|
||||
}
|
||||
|
||||
.site-navbar__cta {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 32px;
|
||||
padding: 0 16px;
|
||||
border-radius: 999px;
|
||||
background: var(--bl-accent);
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
transition: var(--bl-transition);
|
||||
}
|
||||
|
||||
.site-navbar__cta:hover {
|
||||
background: var(--bl-accent-strong);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
@media (max-width: 860px) {
|
||||
.site-navbar__toggle {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.site-navbar__links,
|
||||
.site-navbar__cta {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-navbar__inner {
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user