fix(theme-press): scrollTo by hash

This commit is contained in:
YunYouJun 2023-10-07 01:58:43 +08:00
parent 8390fd2276
commit a786208a9e
14 changed files with 349 additions and 81 deletions

View File

@ -0,0 +1,46 @@
<script lang="ts" setup>
import pkg from '../../package.json'
</script>
<template>
<div text="white sm" bg="dark" rounded-lg>
<pre>
🌌 Valaxy <span text-blue>v{{ pkg.version }}</span>
<span text-cyan>?</span> Select a type: <span op="70"> - Use arrow-keys. Return to submit.</span>
<span text-cyan> Blog <span op="70">- For Most Users</span></span> <span text-purple>Press Enter</span>
<span text-green>Theme <span op="70">- For Theme Developers</span></span>
<span text-yellow>Addon <span op="70">- For Addon Developers</span></span>
<span text-cyan>?</span> Project name: <span op="70"> valaxy-blog</span> <span text-purple>Press Enter</span>
📁 <span op="70">/root/repos/valaxy-blog</span>
<span op="70">Scaffolding project in</span> valaxy-blog <span op="70">...</span>
<span text-green>Done.</span>
<span text-cyan>?</span> Install and start it now? <span op="70"> (Y/n)</span> <span text-purple>Press Y</span>
<span text-cyan>?</span> Choose the agent <span op="70"> - Use arrow-keys. Return to submit.</span>
npm
yarn
<span text-cyan> pnpm </span><span text-purple>Press Enter</span>
<!-- Done in 20.5s. --></pre>
<!-- > valaxy-blog@0.0.0 dev /root/repos/valaxy-blog
> valaxy
Resolve valaxyConfig from /root/repos/valaxy-blog/valaxy.config.ts
Resolve siteConfig from /root/repos/valaxy-blog/site.config.ts
Resolve valaxy.config.ts from theme(yun)
Resolve addons from /root/repos/valaxy-blog
🌌 Valaxy v0.15.5
🪐 theme > yun
📁 /root/repos/valaxy-blog
Preview > http://localhost:4860/
Network > http://172.19.185.146:4860/
shortcuts > restart | open | qr | edit -->
</div>
</template>

View File

@ -43,6 +43,7 @@ useScriptTag('//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js')
```
3. 如果文章中不想使用外链图片,建议按照以下格式创建文件夹及引用图片,便于管理和迁移。
```txt
posts
├─ your-post
@ -57,8 +58,8 @@ posts
![](./a.png)
![](./b.png)
```
:::
:::
::: en
@ -67,9 +68,10 @@ The following are some of our recommended best practices, but you do not need to
1. It is recommended to name folders and files in English.
```txt
blog/pages/posts/your-post. md
blog/pages/posts/your-post.md
```
2. When inserting third-party/large amounts of dynamic content, priority should be given to encapsulating it as a component and placing it in `blog/components`, and introducing it through component tag names.
2. When inserting third-party/large amounts of dynamic content, priority should be given to encapsulating it as a component and placing it in `blog/components`, and introducing it through component tag names.
```vue
// blog/components/BszComponent.vue
@ -112,5 +114,4 @@ posts
![](./b.png)
```
:::

View File

@ -148,6 +148,14 @@ All icon names added to `config.unocss.safelist` will be ready for hot reloading
### Syntax Highlighting {lang="en"}
::: en
> More info about syntax highlighting can be found at [Markdown Syntax Highlighting](/guide/markdown#syntax-highlighting).
:::
::: zh-CN
> 更多关于代码高亮的信息请参见 [Markdown 代码高亮](/guide/markdown#%25E4%25BB%25A3%25E7%25A0%2581%25E8%25A1%258C%25E9%25AB%2598%25E4%25BA%25AE)。
:::
::: zh-CN
基于 [Shiki](https://github.com/shikijs/shiki) 实现。
Valaxy 支持 `vue` 等语法高亮,拷贝代码,高亮其中某一行。

View File

@ -119,10 +119,6 @@ If you are a Windows user, I strongly recommend using a Unix-like shell (such as
</div>
```bash
npm init valaxy
```
::: zh-CN
> 由于 `npm init` 会缓存您此前下载的版本,我更推荐您使用 `pnpm` 来创建模版。
> 安装 [pnpm](https://pnpm.io/)`npm i -g pnpm`
@ -133,22 +129,34 @@ npm init valaxy
> Install [pnpm](https://pnpm.io/)`npm i -g pnpm`
:::
```bash
::: code-group
```bash [pnpm]
pnpm create valaxy
```
```bash [npm]
npm init valaxy
```
:::
::: details You will be greeted with a few simple questions.
<CreateValaxyTooltip />
:::
::: zh-CN
跟随命令行提示完成创建!
> 默认使用主题 [valaxy-theme-yun](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-yun/),当然您也可以安装使用任意其他主题。
> 本文档同样是一个 Valaxy 主题 [valaxy-theme-press](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-press/),它的灵感来自 VitePress。
> 本文档同样是一个 Valaxy 主题 [valaxy-theme-press](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-press/),它的灵感来自 [VitePress](https://vitepress.dev/)
:::
::: en
Follow the prompt in the commandline to complete the process!
> The default theme used is [valaxy-theme-yun](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-yun/), but you can also install any other themes.
> This documentation is also a Valaxy theme: [valaxy-theme-press](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-press/).
> This documentation is also a Valaxy theme: [valaxy-theme-press](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-press/). It is inspired by [VitePress](https://vitepress.dev/).
:::
## Usage {lang="en"}
@ -169,12 +177,20 @@ Follow the prompt in the commandline to complete the process!
Install the dependencies:
:::
```bash
::: code-group
```bash [pnpm]
# install
pnpm i
```
```bash [npm]
# install
npm i
# or pnpm i
```
::::
::: zh-CN
启动预览:
:::
@ -183,12 +199,20 @@ npm i
Start a preview:
:::
```bash
::: code-group
```bash [pnpm]
# start
pnpm dev
```
```bash [npm]
# start
npm run dev
# or pnpm dev
```
::::
::: zh-CN
博客创建完毕,查看本地 `http://localhost:4859/`,玩的开心!
@ -235,7 +259,17 @@ See [Deployment](/guide/deploy) for deployment guide.
## 升级 {lang="zh-CN"}
```bash
::: code-group
```bash [pnpm]
cd your-blog
# upgrade valaxy
pnpm add valaxy@latest
# upgrade theme
pnpm add valaxy-theme-yun@latest
```
```bash [npm]
cd your-blog
# upgrade valaxy
npm i valaxy@latest
@ -243,6 +277,8 @@ npm i valaxy@latest
npm i valaxy-theme-yun@latest
```
:::
### pnpm
::: zh-CN

View File

@ -422,3 +422,79 @@ $$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero |
| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ |
## Markdown File Inclusion
**Input**
```md
# Docs
## Basics
<!--@include: ./parts/basics.md-->
```
**Part file** (`parts/basics.md`)
```md
Some getting started stuff.
### Configuration
Can be created using `.foorc.json`.
```
**Equivalent code**
```md
# Docs
## Basics
Some getting started stuff.
### Configuration
Can be created using `.foorc.json`.
```
It also supports selecting a line range:
**Input**
```md
# Docs
## Basics
<!--@include: ./parts/basics.md{3,}-->
```
**Part file** (`parts/basics.md`)
```md
Some getting started stuff.
### Configuration
Can be created using `.foorc.json`.
```
**Equivalent code**
```md
# Docs
## Basics
### Configuration
Can be created using `.foorc.json`.
```
The format of the selected line range can be: `{3,}`, `{,10}`, `{1,10}`
::: warning
Note that this does not throw errors if your file is not present. Hence, when using this feature make sure that the contents are being rendered as expected.
:::

View File

@ -46,11 +46,6 @@ hide: true
- `hide`: 你可以在文章头部添加 hide 属性,来临时隐藏某篇文章。(该文章仍然会被渲染)
- `true` / `all`: 当设置为 `true``all` 时,该文章仍然会被渲染,你可以直接访问链接进行查看。但不会被显示在展示的文章卡片与归档中。
- `index`: 设置为 `index` 时,将只在首页隐藏,归档中仍然展示。(譬如放一些没有必要放在首页的笔记,并在归档中方便自己查看。)
- `excerpt_type`: 预览列表**摘要**的渲染类型(与 `<!-- more -->` 配合使用)
- `md`: 展示原始 Markdown
- `html`: 以 HTML 形式展示
- `text`: 以纯文本形式展示(去除 HTML 标签)
:::
::: en
@ -59,6 +54,31 @@ hide: true
- `hide`: Adding `hide` in the header allows you to hide the article temporarily. (The article will still be rendered)
- `true` / `all`: When set to `true` or `all`, the article will be rendered, and you can view it by visiting the link directly. It will not be displayed in article cards or archives.
- `index`: When set to `index`, it will be hidden only in the front page. It will still be displayed in archives. (You can use this for some notes unnecessary for the front page, but good for the archive for reference sometimes)
:::
## 摘要 {lang="zh-CN"}
## Excerpt {lang="en"}
::: zh-CN
你可以通过插入 `<!-- more -->` 的方式生成摘要excerpt
可通过设置 `excerpt_type` 设置摘要渲染类型。
- `excerpt`: 自定义摘要(优先级高于 `<!-- more -->`
- `excerpt_type`: 预览列表**摘要**的渲染类型(与 `<!-- more -->` 配合使用)
- `md`: 展示原始 Markdown
- `html`: 以 HTML 形式展示
- `text`: 以纯文本形式展示(去除 HTML 标签)
:::
::: en
You can insert `<!--more-->` to generate an excerpt.
You can set the excerpt rendering type by setting `excerpt_type`.
- `excerpt`: Custom excerpt (higher priority than `<!-- more -->`)
- `excerpt_type`: The rendering type for the excerpt in the preview list (Used with `<!-- more -->`)
- `md`: Display as original markdown
- `html`: Display as HTML
@ -66,44 +86,86 @@ hide: true
:::
## 摘要 {lang="zh-CN"}
::: code-group
::: zh-CN
你可以通过插入 `<!-- more -->` 的方式生成摘要excerpt
可通过设置 `excerpt_type` 设置摘要渲染类型。
```md
```md{3,10} [excerpt_type: text]
---
title: 嘿嘿嘿
title: 'excerpt_type: text'
excerpt_type: text
---
这里是摘要
## Header
![yun-bg](https://cdn.yunyoujun.cn/img/bg/stars-timing-0-blur-30px.jpg)
<!-- more -->
这里是正文
Main Content
```
```md{3,10} [excerpt_type: md]
---
title: 'excerpt_type: md'
excerpt_type: md
---
## Header
![yun-bg](https://cdn.yunyoujun.cn/img/bg/stars-timing-0-blur-30px.jpg)
<!-- more -->
Main Content
```
```md{3,10} [excerpt_type: html]
---
title: 'excerpt_type: html'
excerpt_type: html
---
## Header
![yun-bg](https://cdn.yunyoujun.cn/img/bg/stars-timing-0-blur-30px.jpg)
<!-- more -->
Main Content
```
```md{3} [custom excerpt]
---
title: 'custom excerpt'
excerpt: This is a custom excerpt.
---
## Header
![yun-bg](https://cdn.yunyoujun.cn/img/bg/stars-timing-0-blur-30px.jpg)
Main Content
```
:::
## Excerpt {lang="en"}
You will get excerpt:
::: en
You can insert `<!--more-->` to generate an excerpt.
You can set the excerpt rendering type by setting `excerpt_type`.
::: code-group
```md
---
title: Hello
excerpt_type: text
---
```md [excerpt_type: text]
HEADER yun-bg
```
This is the experpt
```md [excerpt_type: md]
## Header ![yun-bg](https://cdn.yunyoujun.cn/img/bg/stars-timing-0-blur-30px.jpg)
```
<!-- more -->
```md [excerpt_type: html]
<!-- Rendered HTML -->
```
Here goes the body
```md [custom excerpt]
This is a custom excerpt.
```
:::

View File

@ -1,11 +1,11 @@
# valaxy-theme-press
This is a theme for valaxy docs.
This is a theme for [valaxy docs](https://valaxy.site/).
Inspired by [vitepress](https://vitepress.dev).
我开发此主题以编写 Valaxy 的初期文档,同时以便发现 valaxy 编写主题中的痛点。
<!-- 它增加了 VitePress 一些所没有的功能,而随着 VitePress 的完善,该主题将不再被维护,文档也将在未来迁移至 VitePress。 -->
它增加了 VitePress 此前默认所没有的一些功能KaTeX、文章分类、单页 CSS i18n + Vue i18n、Vue Router、Pinia 状态管理,组件自动注册等。
- [预览](https://press.valaxy.site)

View File

@ -0,0 +1 @@
export const targetPadding = -40

View File

@ -1 +1,3 @@
export * from './config'
export * from '../composables'

View File

@ -1,9 +1,11 @@
<script lang="ts" setup>
import type { PageData, Post } from 'valaxy'
import { useFrontmatter, useLayout, useSidebar, useSiteConfig } from 'valaxy'
import { computed } from 'vue'
import { scrollTo, useFrontmatter, useLayout, useSidebar, useSiteConfig } from 'valaxy'
import { computed, nextTick } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
import { getLocaleTitle } from '../utils'
import { targetPadding } from '../client'
defineProps<{
frontmatter: Post
@ -19,6 +21,19 @@ const layout = useLayout()
const { locale } = useI18n()
const localeTitle = computed(() => getLocaleTitle(locale.value, frontmatter.value))
const route = useRoute()
nextTick(() => {
if (route.hash) {
setTimeout(() => {
scrollTo(document.body, route.hash, {
smooth: true,
targetPadding,
})
}, 0)
}
})
</script>
<template>

View File

@ -1,4 +1,4 @@
import { defineAppSetup } from 'valaxy'
import { defineAppSetup, scrollTo } from 'valaxy'
import { nextTick } from 'vue'
import 'vitepress/dist/client/theme-default/styles/vars.css'
@ -12,6 +12,8 @@ import 'vitepress/dist/client/theme-default/styles/components/custom-block.css'
// import 'vitepress/dist/client/theme-default/styles/components/vp-sponsor.css'
import { targetPadding } from '../client'
export default defineAppSetup((ctx) => {
const { router, isClient } = ctx
if (!isClient)
@ -46,7 +48,9 @@ export default defineAppSetup((ctx) => {
// still emit the event so we can listen to it in themes
window.dispatchEvent(new Event('hashchange'))
// use smooth scroll when clicking on header anchor links
scrollTo(link, hash, link.classList.contains('header-anchor'))
scrollTo(link, hash, {
smooth: link.classList.contains('header-anchor'),
})
}
}
}
@ -64,39 +68,10 @@ export default defineAppSetup((ctx) => {
return
nextTick(() => {
scrollTo(document.body, to.hash, true)
scrollTo(document.body, to.hash, {
smooth: true,
targetPadding,
})
})
})
})
function scrollTo(el: HTMLElement, hash: string, smooth = false) {
let target: Element | null = null
try {
target = el.classList.contains('header-anchor')
? el
: ((decodeURIComponent(hash) && document.querySelector(decodeURIComponent(hash))) || null)
}
catch (e) {
console.warn(e)
}
if (target) {
const targetPadding = -64
const targetTop
= window.scrollY
+ (target as HTMLElement).getBoundingClientRect().top
+ targetPadding
// only smooth scroll if distance is smaller than screen height.
if (!smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight) {
window.scrollTo(0, targetTop)
}
else {
window.scrollTo({
left: 0,
top: targetTop,
behavior: 'smooth',
})
}
}
}

View File

@ -1,3 +1,9 @@
.katex-display {
overflow-x: auto;
overflow-y: visible;
padding: 8px 0;
}
.katex-display > .katex > .katex-html > .tag {
right: 2px;
}

View File

@ -4,3 +4,4 @@ export * from './time'
export * from './wrap'
export * from './types'
export * from './content'
export * from './router'

View File

@ -0,0 +1,39 @@
export interface ScrollToOptions {
smooth: boolean
targetPadding: number
}
export function scrollTo(el: HTMLElement, hash: string, options: Partial<ScrollToOptions> = {
smooth: true,
targetPadding: -64,
}) {
let target: Element | null = null
try {
target = el.classList.contains('header-anchor')
? el
: ((decodeURIComponent(hash) && document.querySelector(decodeURIComponent(hash))) || null)
}
catch (e) {
console.warn(e)
}
if (target) {
const targetPadding = options?.targetPadding || -64
const targetTop
= window.scrollY
+ (target as HTMLElement).getBoundingClientRect().top
+ targetPadding
// only smooth scroll if distance is smaller than screen height.
if (!options.smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight) {
window.scrollTo(0, targetTop)
}
else {
window.scrollTo({
// left: 0,
top: targetTop,
behavior: 'smooth',
})
}
}
}