mirror of https://github.com/YunYouJun/valaxy
fix(theme-press): router-link instead of a & toc
This commit is contained in:
parent
49bbdb3fe1
commit
7b3c504e61
|
@ -27,4 +27,4 @@ features:
|
|||
details: Go wild with true SSG + SPA architecture. Static on page load, but engage users with 100% interactivity from there.
|
||||
---
|
||||
|
||||
<div m="y-8" text="center 4xl" font="black">🧪 <br /><br />WORK IN PROGRESS</div>
|
||||
<div m="auto y-8" text="center 4xl" font="black">🧪 <br /><br />WORK IN PROGRESS</div>
|
||||
|
|
|
@ -12,7 +12,9 @@ defineProps<{
|
|||
<div class="space-y-5 xl:col-span-3">
|
||||
<div class="space-y-6">
|
||||
<h2 class="text-2xl leading-8 font-bold tracking-tight">
|
||||
<a class="text-gray-900" :href="post.path">{{ post.title }}</a>
|
||||
<router-link class="text-gray-900" :to="post.path || ''">
|
||||
{{ post.title }}
|
||||
</router-link>
|
||||
</h2>
|
||||
<div
|
||||
v-if="post.excerpt"
|
||||
|
@ -21,7 +23,9 @@ defineProps<{
|
|||
/>
|
||||
</div>
|
||||
<div class="text-base leading-6 font-medium">
|
||||
<a class="link" aria-label="read more" :href="post.path">Read more →</a>
|
||||
<router-link class="link" aria-label="read more" :to="post.path || ''">
|
||||
Read more →
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<script lang="ts" setup>
|
||||
// import { useI18n } from 'vue-i18n'
|
||||
import { useData, useFrontmatter } from 'valaxy'
|
||||
import { useFrontmatter } from 'valaxy'
|
||||
import { useAppStore } from 'valaxy/client/stores/app'
|
||||
import PressOutline from './PressOutline.vue'
|
||||
|
||||
const frontmatter = useFrontmatter()
|
||||
const data = useData()
|
||||
// const { t } = useI18n()
|
||||
const app = useAppStore()
|
||||
</script>
|
||||
|
||||
|
@ -28,7 +26,7 @@ const app = useAppStore()
|
|||
:class="app.isRightSidebarOpen && 'open'"
|
||||
>
|
||||
<div class="aside-container lt-xl:fixed" flex="~ col">
|
||||
<PressToc v-if="frontmatter.toc !== false" :headers="data.headers || []" />
|
||||
<PressOutline v-if="frontmatter.toc !== false" />
|
||||
<div class="flex-grow" />
|
||||
<div v-if="$slots.default" class="custom-container">
|
||||
<slot />
|
||||
|
|
|
@ -1,34 +1,21 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { Header } from 'valaxy'
|
||||
import { ref } from 'vue'
|
||||
import {
|
||||
resolveHeaders,
|
||||
useActiveAnchor,
|
||||
useFrontmatter,
|
||||
useOutline,
|
||||
} from 'valaxy'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useThemeConfig } from '../composables'
|
||||
|
||||
const props = defineProps<{ headers: Header[] }>()
|
||||
|
||||
const frontmatter = useFrontmatter()
|
||||
const { t } = useI18n()
|
||||
const themeConfig = useThemeConfig()
|
||||
|
||||
const { locale, t } = useI18n()
|
||||
const container = ref()
|
||||
const marker = ref()
|
||||
|
||||
useActiveAnchor(container, marker)
|
||||
|
||||
const resolvedHeaders = computed(() => {
|
||||
return resolveHeaders(props.headers || [])
|
||||
})
|
||||
|
||||
function handleClick({ target: el }: Event) {
|
||||
const id = `#${(el as HTMLAnchorElement).href!.split('#')[1]}`
|
||||
const heading = document.querySelector(decodeURIComponent(id)) as HTMLAnchorElement
|
||||
heading?.focus()
|
||||
}
|
||||
const { headers, handleClick } = useOutline()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -45,26 +32,12 @@ function handleClick({ target: el }: Event) {
|
|||
Table of Contents for current page
|
||||
</span>
|
||||
|
||||
<ul class="va-toc relative z-1">
|
||||
<li
|
||||
v-for="{ text, link, children, hidden, lang } in resolvedHeaders"
|
||||
v-show="!hidden"
|
||||
:key="link"
|
||||
class="va-toc-item"
|
||||
:lang="lang || locale"
|
||||
>
|
||||
<a class="outline-link" :href="link" @click="handleClick">
|
||||
{{ text }}
|
||||
</a>
|
||||
<ul v-if="children && frontmatter.outline === 'deep'">
|
||||
<li v-for="item in children" v-show="!item.hidden" :key="item.link" :lang="lang || locale">
|
||||
<a class="outline-link" p="l-3" :href="link" @click="handleClick">
|
||||
{{ item.text }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<PressOutlineItem
|
||||
class="va-toc relative z-1"
|
||||
:headers="headers"
|
||||
:on-click="handleClick"
|
||||
root
|
||||
/>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,48 @@
|
|||
<script setup lang="ts">
|
||||
import type { MenuItem } from 'valaxy'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
defineProps<{
|
||||
headers: MenuItem[]
|
||||
onClick: (e: MouseEvent) => void
|
||||
root?: boolean
|
||||
}>()
|
||||
|
||||
const { locale } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul :class="root ? 'root' : 'nested'">
|
||||
<li v-for="{ children, link, title, lang } in headers" :key="link" class="va-toc-item" :lang="lang || locale">
|
||||
<a class="outline-link" :href="link" @click="onClick">{{ title }}</a>
|
||||
<template v-if="children?.length">
|
||||
<PressOutlineItem :headers="children" :on-click="onClick" />
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.va-toc {
|
||||
.va-toc-item {
|
||||
.outline-link {
|
||||
color: var(--va-c-text-light);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: color 0.5s;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
color: var(--va-c-brand);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.nested {
|
||||
padding-left: 0.8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -26,7 +26,7 @@ const isHome = useLayout('home')
|
|||
}" p="t-6"
|
||||
>
|
||||
<slot name="main">
|
||||
<div class="content" m="y-0" flex="~ col grow" w="full" p="x-12 lt-md:0">
|
||||
<div class="content" :class="{ 'm-auto': !hasSidebar }" m="y-0" flex="~ col grow" w="full" p="x-12 lt-md:0">
|
||||
<slot name="main-header" />
|
||||
<slot name="main-header-after" />
|
||||
|
||||
|
|
|
@ -21,9 +21,9 @@ const themeConfig = useThemeConfig()
|
|||
|
||||
<template>
|
||||
<div class="press-navbar flex justify-between items-center px-6 py-4" :class="{ 'has-sidebar': hasSidebar }">
|
||||
<a class="text-xl" href="/" :aria-label="config.title">
|
||||
<router-link class="text-xl" to="/" :aria-label="config.title">
|
||||
<span class="md:inline">{{ config.title }}</span>
|
||||
</a>
|
||||
</router-link>
|
||||
<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" />
|
||||
|
|
|
@ -29,10 +29,9 @@ const open = ref(false)
|
|||
</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">
|
||||
<AppLink v-for="itemLink in item.items" :key="itemLink.text" class="menu-item" :to="itemLink.link">
|
||||
{{ itemLink.text }}
|
||||
<div class="icon-link inline-block" i-ri-arrow-right-up-line />
|
||||
</a>
|
||||
</AppLink>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -105,18 +104,4 @@ const open = ref(false)
|
|||
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>
|
||||
|
|
|
@ -9,14 +9,17 @@ const route = useRoute()
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<a
|
||||
<AppLink
|
||||
class="press-nav-item-link p-x-3"
|
||||
:class="{
|
||||
active: route.path === item.link,
|
||||
}"
|
||||
:href="item.link"
|
||||
:to="item.link"
|
||||
rel="noopener"
|
||||
>{{ item.text }}</a>
|
||||
show-external-icon
|
||||
>
|
||||
{{ item.text }}
|
||||
</AppLink>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -58,11 +58,10 @@ export default defineAppSetup((ctx) => {
|
|||
|
||||
function scrollTo(el: HTMLElement, hash: string, smooth = false) {
|
||||
let target: Element | null = null
|
||||
|
||||
try {
|
||||
target = el.classList.contains('header-anchor')
|
||||
? el
|
||||
: document.querySelector(decodeURIComponent(hash))
|
||||
: (decodeURIComponent(hash) && document.querySelector(decodeURIComponent(hash))) || null
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(e)
|
||||
|
|
|
@ -13,13 +13,7 @@ const marker = ref()
|
|||
|
||||
useActiveAnchor(container, marker)
|
||||
|
||||
const { headers } = useOutline()
|
||||
|
||||
function handleClick({ target: el }: Event) {
|
||||
const id = `#${(el as HTMLAnchorElement).href!.split('#')[1]}`
|
||||
const heading = document.querySelector(decodeURIComponent(id)) as HTMLAnchorElement
|
||||
heading?.focus()
|
||||
}
|
||||
const { headers, handleClick } = useOutline()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -5,9 +5,9 @@ const themeConfig = useThemeConfig()
|
|||
|
||||
<template>
|
||||
<div class="links">
|
||||
<a v-for="item, i in themeConfig.pages" :key="i" class="link-item yun-icon-btn" :href="item.url" :title="item.name" :target="item.url.startsWith('http') ? '_blank' : ''" :style="`color:${item.color}`">
|
||||
<AppLink v-for="item, i in themeConfig.pages" :key="i" class="link-item yun-icon-btn" :to="item.url" :title="item.name" :style="`color:${item.color}`">
|
||||
<div :class="item.icon" class="icon" />
|
||||
</a>
|
||||
</AppLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -21,7 +21,7 @@ const themeConfig = useThemeConfig()
|
|||
.link-item {
|
||||
display: inline-flex;
|
||||
|
||||
.icon {
|
||||
.icon {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
|
|
@ -30,8 +30,4 @@ html.dark {
|
|||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<script setup lang="ts">
|
||||
// https://router.vuejs.org/guide/advanced/extending-router-link.html#extending-routerlink
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
showExternalIcon?: boolean
|
||||
to: string
|
||||
}>()
|
||||
|
||||
|
@ -13,6 +15,7 @@ const isExternalLink = computed(() => {
|
|||
<template>
|
||||
<a v-if="isExternalLink" v-bind="$attrs" :href="to" target="_blank">
|
||||
<slot />
|
||||
<div v-if="showExternalIcon" class="icon-link inline-block" i-ri-arrow-right-up-line />
|
||||
</a>
|
||||
<router-link v-else v-bind="$props as any">
|
||||
<slot />
|
||||
|
|
|
@ -17,7 +17,7 @@ const { t } = useI18n()
|
|||
const content = ref()
|
||||
function updateDom() {
|
||||
wrapTable(content.value)
|
||||
onContentUpdated.value()
|
||||
onContentUpdated.value?.()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -208,8 +208,17 @@ export const useOutline = () => {
|
|||
headers.value = getHeaders(pageOutline.value)
|
||||
}
|
||||
|
||||
const handleClick = ({ target: el }: Event) => {
|
||||
const id = `#${(el as HTMLAnchorElement).href!.split('#')[1]}`
|
||||
const heading = document.querySelector(
|
||||
decodeURIComponent(id),
|
||||
) as HTMLAnchorElement
|
||||
heading?.focus()
|
||||
}
|
||||
|
||||
return {
|
||||
headers,
|
||||
handleClick,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
|
||||
.markdown-body {
|
||||
code {
|
||||
font-size: inherit;
|
||||
// relative h1, etc
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
div[class*="language-"] {
|
||||
|
|
Loading…
Reference in New Issue