Merge branch 'main' into edison/feat/vaporMode

pull/5179/head
edison 3 months ago committed by GitHub
commit 45b6bee3f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -13,4 +13,4 @@
---
> [!TIP]
> The author of this PR can publish a _preview release_ by commenting `/publish` below.
> The author can publish a _preview release_ by commenting `/publish` after creating the PR.

1
.gitignore vendored

@ -16,3 +16,4 @@ node_modules
pnpm-global
TODOs.md
*.timestamp-*.mjs
.claude

@ -2,7 +2,6 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"isolatedModules": false,
"baseUrl": ".",
"types": ["node", "vitest/globals"],
"paths": {
"client/*": ["../src/client/*"],

@ -13,9 +13,9 @@
"@lunariajs/core": "^0.1.1",
"markdown-it-mathjax3": "^4.3.2",
"open-cli": "^8.0.0",
"postcss-rtlcss": "^5.7.1",
"postcss-rtlcss": "^6.0.0",
"vitepress": "workspace:*",
"vitepress-plugin-group-icons": "1.7.1",
"vitepress-plugin-llms": "^1.12.0"
"vitepress-plugin-group-icons": "^1.7.5",
"vitepress-plugin-llms": "^1.12.1"
}
}

@ -99,14 +99,14 @@
"@docsearch/css": "^4.6.2",
"@docsearch/js": "^4.6.2",
"@docsearch/sidepanel-js": "^4.6.2",
"@iconify-json/simple-icons": "^1.2.75",
"@iconify-json/simple-icons": "^1.2.78",
"@shikijs/core": "^4.0.2",
"@shikijs/transformers": "^4.0.2",
"@shikijs/types": "^4.0.2",
"@types/markdown-it": "^14.1.2",
"@vitejs/plugin-vue": "https://pkg.pr.new/@vitejs/plugin-vue@766",
"@vue/devtools-api": "^8.1.1",
"@vue/shared": "^3.5.31",
"@vue/shared": "^3.5.32",
"@vueuse/core": "^14.2.1",
"@vueuse/integrations": "^14.2.1",
"focus-trap": "^8.0.1",
@ -117,7 +117,9 @@
"vue": "https://pkg.pr.new/vue@11e41c2"
},
"devDependencies": {
"@clack/prompts": "^1.1.0",
"@clack/prompts": "^1.2.0",
"@emnapi/core": "^1.10.0",
"@emnapi/runtime": "^1.10.0",
"@iconify/utils": "^3.1.0",
"@mdit-vue/plugin-component": "^3.0.2",
"@mdit-vue/plugin-frontmatter": "^3.0.2",
@ -140,21 +142,21 @@
"@types/markdown-it-container": "^4.0.0",
"@types/markdown-it-emoji": "^3.0.1",
"@types/minimist": "^1.2.5",
"@types/node": "^25.5.0",
"@types/picomatch": "^4.0.2",
"@types/node": "^25.6.0",
"@types/picomatch": "^4.0.3",
"@types/prompts": "^2.4.9",
"chokidar": "^5.0.0",
"conventional-changelog": "^7.2.0",
"conventional-changelog-angular": "^8.3.0",
"conventional-changelog-angular": "^8.3.1",
"cross-spawn": "^7.0.6",
"esbuild": "^0.27.4",
"esbuild": "^0.27.7",
"execa": "^9.6.1",
"fs-extra": "^11.3.4",
"get-port": "^7.2.0",
"gray-matter": "^4.0.3",
"lint-staged": "^16.4.0",
"lodash.template": "^4.5.0",
"lru-cache": "^11.2.7",
"lodash.template": "^4.18.1",
"lru-cache": "^11.3.5",
"markdown-it": "^14.1.1",
"markdown-it-anchor": "^9.2.0",
"markdown-it-async": "^2.2.0",
@ -164,7 +166,7 @@
"markdown-it-emoji": "^3.0.0",
"markdown-it-mathjax3": "^4.3.2",
"minimist": "^1.2.8",
"nanoid": "^5.1.7",
"nanoid": "^5.1.9",
"obug": "^2.1.1",
"ora": "^9.3.0",
"oxc-minify": "^0.98.0",
@ -173,25 +175,25 @@
"path-to-regexp": "^6.3.0",
"picocolors": "^1.1.1",
"picomatch": "^4.0.4",
"playwright-chromium": "^1.58.2",
"playwright-chromium": "^1.59.1",
"polka": "^1.0.0-next.28",
"postcss": "^8.5.6",
"postcss-selector-parser": "^7.1.1",
"prettier": "^3.8.1",
"prettier": "^3.8.3",
"prompts": "^2.4.2",
"punycode": "^2.3.1",
"rollup": "^4.60.0",
"rollup": "^4.60.1",
"rollup-plugin-dts": "6.1.1",
"rollup-plugin-esbuild": "^6.2.1",
"semver": "^7.7.4",
"simple-git-hooks": "^2.13.1",
"sirv": "^3.0.2",
"sitemap": "^9.0.1",
"tinyglobby": "^0.2.15",
"typescript": "^5.9.3",
"tinyglobby": "^0.2.16",
"typescript": "^6.0.3",
"vitest": "4.0.0-beta.4",
"vue-tsc": "^3.2.6",
"wait-on": "^9.0.4"
"wait-on": "^9.0.5"
},
"peerDependencies": {
"markdown-it-mathjax3": "^4",

File diff suppressed because it is too large Load Diff

@ -215,7 +215,7 @@ if (inBrowser) {
// scroll to hash on new tab during dev
if (import.meta.env.DEV && location.hash) {
scrollTo(location.hash)
setTimeout(() => scrollTo(location.hash), 100)
}
})
})

@ -3,7 +3,7 @@ import { inject, markRaw, nextTick, reactive, readonly } from 'vue'
import type { Awaitable, PageData, PageDataPayload } from '../shared'
import { notFoundPageData, treatAsHtml } from '../shared'
import { siteDataRef } from './data'
import { getScrollOffset, inBrowser, withBase } from './utils'
import { inBrowser, withBase } from './utils'
export interface Route {
path: string
@ -26,8 +26,6 @@ export interface Router {
options?: {
// @internal
initialLoad?: boolean
// Whether to smoothly scroll to the target position.
smoothScroll?: boolean
// Whether to replace the current history entry.
replace?: boolean
}
@ -145,7 +143,7 @@ export function createRouter(
history.replaceState({}, '', href)
}
if (!initialLoad) scrollTo(targetLoc.hash, false, scrollPosition)
if (!initialLoad) scrollTo(targetLoc.hash, scrollPosition)
})
}
}
@ -232,10 +230,7 @@ export function createRouter(
// only intercept inbound html links
if (origin === currentLoc.origin && treatAsHtml(pathname)) {
e.preventDefault()
router.go(href, {
// use smooth scroll when clicking on header anchor links
smoothScroll: link.classList.contains('header-anchor')
})
router.go(href)
}
},
{ capture: true }
@ -270,7 +265,7 @@ export function useRoute(): Route {
return useRouter().route
}
export function scrollTo(hash: string, smooth = false, scrollPosition = 0) {
export function scrollTo(hash: string, scrollPosition = 0) {
if (!hash || scrollPosition) {
window.scrollTo(0, scrollPosition)
return
@ -284,21 +279,8 @@ export function scrollTo(hash: string, smooth = false, scrollPosition = 0) {
}
if (!target) return
const targetTop =
window.scrollY +
target.getBoundingClientRect().top -
getScrollOffset() +
Number.parseInt(window.getComputedStyle(target).paddingTop, 10) || 0
const behavior = window.matchMedia('(prefers-reduced-motion)').matches
? 'instant'
: // only smooth scroll if distance is smaller than screen height
smooth && Math.abs(targetTop - window.scrollY) <= window.innerHeight
? 'smooth'
: 'auto'
const scrollToTarget = () => {
window.scrollTo({ left: 0, top: targetTop, behavior })
target.scrollIntoView({ block: 'start' })
// focus the target element for better accessibility
target.focus({ preventScroll: true })
@ -361,12 +343,7 @@ function normalizeHref(href: string): string {
async function changeRoute(
href: string,
{
smoothScroll = false,
initialLoad = false,
replace = false,
hasTextFragment = false
} = {}
{ initialLoad = false, replace = false, hasTextFragment = false } = {}
): Promise<boolean> {
const loc = normalizeHref(location.href)
const nextUrl = new URL(href, location.origin)
@ -374,7 +351,7 @@ async function changeRoute(
if (href === loc) {
if (!initialLoad) {
if (!hasTextFragment) scrollTo(nextUrl.hash, smoothScroll)
if (!hasTextFragment) scrollTo(nextUrl.hash)
return false
}
} else {
@ -395,7 +372,7 @@ async function changeRoute(
newURL: nextUrl.href
})
)
if (!hasTextFragment) scrollTo(nextUrl.hash, smoothScroll)
if (!hasTextFragment) scrollTo(nextUrl.hash)
}
return false

@ -102,36 +102,3 @@ export function defineClientComponent(
}
}
}
export function getScrollOffset() {
let scrollOffset = siteDataRef.value.scrollOffset
let offset = 0
let padding = 24
if (typeof scrollOffset === 'object' && 'padding' in scrollOffset) {
padding = scrollOffset.padding
scrollOffset = scrollOffset.selector
}
if (typeof scrollOffset === 'number') {
offset = scrollOffset
} else if (typeof scrollOffset === 'string') {
offset = tryOffsetSelector(scrollOffset, padding)
} else if (Array.isArray(scrollOffset)) {
for (const selector of scrollOffset) {
const res = tryOffsetSelector(selector, padding)
if (res) {
offset = res
break
}
}
}
return offset
}
function tryOffsetSelector(selector: string, padding: number): number {
const el = document.querySelector(selector)
if (!el) return 0
const bot = el.getBoundingClientRect().bottom
if (bot < 0) return 0
return bot + padding
}

@ -19,7 +19,6 @@ export { useRoute, useRouter } from './app/router'
export {
_escapeHtml,
defineClientComponent,
getScrollOffset,
inBrowser,
onContentUpdated,
withBase

@ -1,4 +1,3 @@
import { getScrollOffset } from 'vitepress'
import type { DefaultTheme } from 'vitepress/theme'
import { onMounted, onUnmounted, onUpdated, type Ref } from 'vue'
import { throttleAndDebounce } from '../support/utils'
@ -115,7 +114,9 @@ export function useActiveAnchor(
const headers = resolvedHeaders
.map(({ element, link }) => ({
link,
top: getAbsoluteTop(element)
top: getAbsoluteTop(element),
scrollMarginTop:
Number.parseFloat(getComputedStyle(element).scrollMarginTop) || 0
}))
.filter(({ top }) => !Number.isNaN(top))
.sort((a, b) => a.top - b.top)
@ -140,8 +141,8 @@ export function useActiveAnchor(
// find the last header above the top of viewport
let activeLink: string | null = null
for (const { link, top } of headers) {
if (top > scrollY + getScrollOffset() + 4) {
for (const { link, top, scrollMarginTop } of headers) {
if (top > scrollY + scrollMarginTop + 4) {
break
}
activeLink = link

@ -11,6 +11,9 @@
position: relative;
font-weight: 600;
outline: none;
scroll-margin-top: calc(
var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 24px
);
}
.vp-doc h1 {

@ -1,13 +1,12 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"outDir": "../../dist/client",
"declaration": true,
"declarationDir": "../../dist/client-types",
"types": ["../../client.d.ts", "@types/node"],
"paths": {
"vitepress": ["index.ts"],
"vitepress": ["./index.ts"],
"vitepress/theme": ["../../theme.d.ts"]
}
},

@ -335,7 +335,6 @@ export async function resolveSiteData(
appearance: userConfig.appearance ?? true,
themeConfig: userConfig.themeConfig || {},
locales: userConfig.locales || {},
scrollOffset: userConfig.scrollOffset ?? 134,
cleanUrls: !!userConfig.cleanUrls,
contentProps: userConfig.contentProps,
additionalConfig: userConfig.additionalConfig

@ -88,20 +88,6 @@ export interface UserConfig<
*/
vite?: ViteConfig & { configFile?: string | false }
/**
* Configure the scroll offset when the theme has a sticky header.
* Can be a number or a selector element to get the offset from.
* Can also be an array of selectors in case some elements will be
* invisible due to responsive layout. VitePress will fallback to the next
* selector if a selector fails to match, or the matched element is not
* currently visible in viewport.
*/
scrollOffset?:
| number
| string
| string[]
| { selector: string | string[]; padding: number }
/**
* Enable MPA / zero-JS mode.
* @experimental

@ -1,7 +1,6 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"outDir": "../../dist/node",
"types": ["node"],
"sourceMap": true

@ -1,7 +1,6 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"lib": ["esnext", "dom", "dom.iterable"]
},
"include": ["."]

5
types/shared.d.ts vendored

@ -136,11 +136,6 @@ export interface SiteData<ThemeConfig = any> {
| 'force-auto'
| (Omit<UseDarkOptions, 'initialValue'> & { initialValue?: 'dark' })
themeConfig: ThemeConfig
scrollOffset:
| number
| string
| string[]
| { selector: string | string[]; padding: number }
locales: LocaleConfig<ThemeConfig>
localeIndex?: string
contentProps?: Record<string, any>

Loading…
Cancel
Save