mirror of https://github.com/YunYouJun/valaxy
feat(theme-press): add navbar (#86)
* refactor(theme-press): fix outline-title color * feat(theme-press): add nav * fix(theme-press): modify types-file-import way * fix(theme-press): modify nav-config place * fix(theme-press): del items-centertext-sm Co-authored-by: 云游君 <me@yunyoujun.cn>
This commit is contained in:
parent
d937147bf8
commit
5a5abe161b
|
@ -10,7 +10,35 @@ export default defineConfig({
|
|||
description: 'Valaxy Site Docs',
|
||||
|
||||
theme: 'press',
|
||||
themeConfig: {},
|
||||
themeConfig: {
|
||||
nav: [
|
||||
{
|
||||
text: 'FAQ',
|
||||
link: '/dev/faq',
|
||||
},
|
||||
{
|
||||
text: 'Guide',
|
||||
link: '/guide/getting-started',
|
||||
},
|
||||
{
|
||||
text: 'Addons',
|
||||
items: [
|
||||
{
|
||||
text: 'index',
|
||||
link: '/addons',
|
||||
},
|
||||
{
|
||||
text: 'use',
|
||||
link: '/addons/use',
|
||||
},
|
||||
{
|
||||
text: 'write',
|
||||
link: '/addons/write',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
vite: {
|
||||
base: '/',
|
||||
|
|
|
@ -106,6 +106,7 @@ function handleClick({ target: el }: Event) {
|
|||
line-height: 28px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--pr-c-text-1);
|
||||
}
|
||||
|
||||
.outline-link {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
import { useConfig, useSidebar } from 'valaxy'
|
||||
import { useThemeConfig } from '../../composables'
|
||||
import PressSwitchAppearance from './PressSwitchAppearance.vue'
|
||||
import PressNavItemLink from './PressNavItemLink.vue'
|
||||
import PressNavItemGroup from './PressNavItemGroup.vue'
|
||||
|
||||
defineProps<{
|
||||
isScreenOpen?: boolean
|
||||
|
@ -22,18 +24,11 @@ const themeConfig = useThemeConfig()
|
|||
<a class="text-xl" href="/" :aria-label="config.title">
|
||||
<span class="md:inline">{{ config.title }}</span>
|
||||
</a>
|
||||
<div class="flex justify-center items-centertext-sm leading-5">
|
||||
<template v-for="(item, i) in themeConfig.nav" :key="i">
|
||||
<a
|
||||
class="hover:text-gray-700"
|
||||
:href="item.link"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>{{ item.text }}</a>
|
||||
|
||||
<span v-if="i !== themeConfig.nav.length - 1" class="mr-2 ml-2">·</span>
|
||||
<div class="self-stretch flex justify-center items-center text-sm leading-5">
|
||||
<template v-for="item in themeConfig.nav" :key="item.text">
|
||||
<PressNavItemLink v-if="'link' in item" :item="item" />
|
||||
<PressNavItemGroup v-else :item="item" />
|
||||
</template>
|
||||
|
||||
<PressToggleLocale m="x-2" />
|
||||
<PressSwitchAppearance m="l-2" />
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import type { NavItemGroup } from '../../types'
|
||||
defineProps<{
|
||||
item: NavItemGroup
|
||||
}>()
|
||||
|
||||
const open = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
ref="el"
|
||||
class="self-stretch relative group"
|
||||
:aria-expanded="open"
|
||||
aria-haspopup="true"
|
||||
@mouseenter="open = true"
|
||||
@mouseleave="open = false"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="button flex items-center"
|
||||
@click="open = !open"
|
||||
>
|
||||
<span class="text">
|
||||
{{ item.text }}
|
||||
</span>
|
||||
<div i-ri-arrow-drop-down-line />
|
||||
</button>
|
||||
|
||||
<div class="menu flex items-center flex-col grow">
|
||||
<a v-for="itemLink in item.items" :key="itemLink.text" class="menu-item" :href="itemLink.link">
|
||||
{{ itemLink.text }}
|
||||
<div class="icon-link inline-block" i-ri-arrow-right-up-line />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.group{
|
||||
top: calc(var(--pr-nav-height) / 2 - 10px);
|
||||
}
|
||||
.group .button{
|
||||
color: var(--pr-nav-text);
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.group[aria-expanded="true"] .button{
|
||||
color: rgba(60, 60, 60, 0.70);
|
||||
transition: color 0.25s;
|
||||
|
||||
.dark &{
|
||||
color: rgba(235, 235, 235, 0.6)
|
||||
}
|
||||
}
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
right: 0;
|
||||
|
||||
min-width: 128px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.25s, visibility 0.25s, transform 0.25s;
|
||||
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
border: 1px solid rgba(60, 60, 60, 0.12);
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08);
|
||||
.dark &{
|
||||
background-color: #242424;
|
||||
}
|
||||
|
||||
&-item{
|
||||
display: block;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
padding: 0 6px;
|
||||
border-radius: 6px;
|
||||
color: var(--pr-nav-text);
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
transition: background-color .25s,color .25s;
|
||||
|
||||
&:hover{
|
||||
background-color: #f1f1f1;
|
||||
color: var(--va-c-brand);
|
||||
|
||||
.dark &{
|
||||
background-color: #2f2f2f;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.group[aria-expanded="true"] > .menu {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.icon-link{
|
||||
display: inline-block;
|
||||
margin-top: -1px;
|
||||
margin-left: 4px;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
color: rgba(60, 60, 60, 0.33);
|
||||
transition: color .25s;
|
||||
|
||||
.dark &{
|
||||
color: rgba(235, 235,235, 0.38)
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,36 @@
|
|||
<script lang="ts" setup>
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { NavItemLink } from '../../types'
|
||||
defineProps<{
|
||||
item: NavItemLink
|
||||
}>()
|
||||
|
||||
const route = useRoute()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a
|
||||
class="press-nav-item-link p-x-3"
|
||||
:class="{
|
||||
active: route.path === item.link,
|
||||
}"
|
||||
:href="item.link"
|
||||
rel="noopener"
|
||||
>{{ item.text }}</a>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.press-nav-item-link{
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--pr-nav-text);
|
||||
transition: color 0.25s;
|
||||
|
||||
&:hover{
|
||||
color: var(--va-c-brand);
|
||||
}
|
||||
}
|
||||
.active{
|
||||
color: var(--va-c-brand);
|
||||
}
|
||||
</style>
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
:root {
|
||||
--pr-c-text-code: #374562;
|
||||
--pr-c-text-1: #213547;
|
||||
|
||||
// aside
|
||||
--pr-aside-text-1: #213547;
|
||||
--pr-aside-text-2: #3c3c3cb3;
|
||||
--pr-aside-text-1: var(--pr-c-text-1);
|
||||
--pr-aside-text-2: rgba(60, 60, 60, 0.702);
|
||||
|
||||
--pr-aside-divider: rgba(60, 60, 60, 0.122);
|
||||
|
||||
|
@ -16,6 +17,7 @@
|
|||
// nav
|
||||
--pr-nav-height: var(--pr-nav-height-mobile);
|
||||
--pr-nav-height-mobile: 60px;
|
||||
--pr-nav-text: var(--pr-c-text-1);
|
||||
|
||||
// z-index
|
||||
--va-z-overlay: var(--pr-z-index-backdrop);
|
||||
|
@ -31,9 +33,9 @@
|
|||
|
||||
.dark {
|
||||
--pr-c-text-code: var(--pr-c-indigo-lighter);
|
||||
--pr-c-text-1: #ffffffde;
|
||||
|
||||
// aside
|
||||
--pr-aside-text-1: #ffffffde;
|
||||
--pr-aside-text-2: #ebebeb99;
|
||||
--pr-aside-divider: rgba(84, 84, 84, 0.48);
|
||||
|
||||
|
|
|
@ -6,6 +6,19 @@ export namespace DocsTheme {
|
|||
export type Sidebar = any
|
||||
}
|
||||
|
||||
export interface NavItemLink {
|
||||
link: string
|
||||
text: string
|
||||
active?: string
|
||||
}
|
||||
|
||||
export interface NavItemGroup {
|
||||
text: string
|
||||
items: NavItemLink[]
|
||||
}
|
||||
|
||||
export type NavItem = NavItemLink | NavItemGroup
|
||||
|
||||
/**
|
||||
* Theme Config
|
||||
*/
|
||||
|
@ -24,12 +37,8 @@ export interface ThemeConfig {
|
|||
primary: string
|
||||
}
|
||||
|
||||
nav: Array<NavItem>
|
||||
sidebar: string[]
|
||||
|
||||
nav: {
|
||||
link: string
|
||||
text: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export type ThemeUserConfig = Partial<ThemeConfig>
|
||||
|
|
Loading…
Reference in New Issue