valaxy 0.19.13 → 0.20.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/components/ValaxyFootnoteTooltip.vue +0 -2
- package/client/components/ValaxyOverlay.vue +1 -1
- package/client/composables/helper/index.ts +2 -0
- package/client/composables/helper/useScreenSize.ts +22 -0
- package/client/composables/outline/anchor.ts +64 -63
- package/client/composables/post/index.ts +1 -0
- package/client/composables/post/usePagination.ts +65 -0
- package/client/composables/sidebar.ts +3 -40
- package/client/modules/floating-vue.ts +9 -1
- package/client/stores/app.ts +0 -7
- package/client/styles/common/code.scss +2 -2
- package/client/styles/components/code-group.scss +3 -4
- package/client/styles/palette.scss +9 -9
- package/client/utils/helper.ts +7 -0
- package/dist/{chunk-X25DVJU7.mjs → chunk-UCIXONQT.mjs} +34 -34
- package/dist/{chunk-J5LLA2M3.cjs → chunk-V2BCVIX4.cjs} +34 -34
- package/dist/{config-BNXiUUii.d.cts → config-DRImYfNf.d.cts} +4 -0
- package/dist/{config-BNXiUUii.d.ts → config-DRImYfNf.d.ts} +4 -0
- package/dist/node/cli/index.cjs +1 -1
- package/dist/node/cli/index.mjs +1 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +1 -1
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.mjs +1 -1
- package/dist/types/index.cjs +1 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.mjs +1 -1
- package/package.json +8 -9
- package/types/config.ts +4 -0
- /package/client/composables/{helper.ts → helper/useInvisibleElement.ts} +0 -0
- /package/dist/{chunk-LD7IYUN2.mjs → chunk-TNTV5UAJ.mjs} +0 -0
- /package/dist/{chunk-2PA6UTKF.cjs → chunk-VWINQN6R.cjs} +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useMediaQuery } from '@vueuse/core'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* breakpoints ref https://tailwindcss.com/docs/screens
|
|
5
|
+
*/
|
|
6
|
+
export function useScreenSize() {
|
|
7
|
+
const isXs = useMediaQuery('(max-width: 639px)')
|
|
8
|
+
const isSm = useMediaQuery('(min-width: 640px)')
|
|
9
|
+
const isMd = useMediaQuery('(min-width: 768px)')
|
|
10
|
+
const isLg = useMediaQuery('(min-width: 1024px)')
|
|
11
|
+
const isXl = useMediaQuery('(min-width: 1280px)')
|
|
12
|
+
const is2xl = useMediaQuery('(min-width: 1536px)')
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
isXs,
|
|
16
|
+
isSm,
|
|
17
|
+
isMd,
|
|
18
|
+
isLg,
|
|
19
|
+
isXl,
|
|
20
|
+
is2xl,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
import type { Ref } from 'vue'
|
|
2
2
|
import { onMounted, onUnmounted, onUpdated } from 'vue'
|
|
3
|
+
import { resolvedHeaders } from '@valaxyjs/utils'
|
|
3
4
|
import { throttleAndDebounce } from '../../utils'
|
|
4
5
|
import { useAside } from '../aside'
|
|
5
6
|
|
|
6
7
|
// magic number to avoid repeated retrieval
|
|
7
|
-
const PAGE_OFFSET =
|
|
8
|
+
const PAGE_OFFSET = 130
|
|
8
9
|
const topOffset = 33
|
|
9
10
|
|
|
11
|
+
function getAbsoluteTop(element: HTMLElement): number {
|
|
12
|
+
let offsetTop = 0
|
|
13
|
+
while (element !== document.body) {
|
|
14
|
+
if (element === null) {
|
|
15
|
+
// child element is:
|
|
16
|
+
// - not attached to the DOM (display: none)
|
|
17
|
+
// - set to fixed position (not scrollable)
|
|
18
|
+
// - body or html element (null offsetParent)
|
|
19
|
+
return Number.NaN
|
|
20
|
+
}
|
|
21
|
+
offsetTop += element.offsetTop
|
|
22
|
+
element = element.offsetParent as HTMLElement
|
|
23
|
+
}
|
|
24
|
+
return offsetTop
|
|
25
|
+
}
|
|
26
|
+
|
|
10
27
|
export function useActiveAnchor(
|
|
11
28
|
container: Ref<HTMLElement>,
|
|
12
29
|
marker: Ref<HTMLElement>,
|
|
@@ -30,63 +47,70 @@ export function useActiveAnchor(
|
|
|
30
47
|
window.removeEventListener('scroll', onScroll)
|
|
31
48
|
})
|
|
32
49
|
|
|
33
|
-
|
|
34
|
-
|
|
50
|
+
const checkActiveLinkInViewport = () => {
|
|
51
|
+
const activeLink = prevActiveLink
|
|
52
|
+
if (!activeLink) {
|
|
53
|
+
// container.value.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
35
54
|
return
|
|
55
|
+
}
|
|
36
56
|
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
const top = activeLink.getBoundingClientRect().top
|
|
58
|
+
const bottom = activeLink.getBoundingClientRect().bottom
|
|
59
|
+
|
|
60
|
+
const parentEl = document.querySelector('.yun-aside') as HTMLElement
|
|
61
|
+
if (parentEl) {
|
|
62
|
+
if (top < parentEl.scrollTop)
|
|
63
|
+
parentEl.scrollTo({ top: 0, behavior: 'smooth' })
|
|
64
|
+
if (bottom > parentEl.offsetHeight + parentEl.scrollTop)
|
|
65
|
+
parentEl.scrollTo({ top: bottom + 40, behavior: 'smooth' })
|
|
66
|
+
}
|
|
67
|
+
}
|
|
40
68
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return links.some((link) => {
|
|
45
|
-
return link.hash === anchor.hash && anchor.offsetParent !== null
|
|
46
|
-
})
|
|
47
|
-
}) as HTMLAnchorElement[]
|
|
69
|
+
function setActiveLink() {
|
|
70
|
+
if (!isAsideEnabled.value)
|
|
71
|
+
return
|
|
48
72
|
|
|
49
73
|
const scrollY = window.scrollY
|
|
50
74
|
const innerHeight = window.innerHeight
|
|
51
75
|
const offsetHeight = document.body.offsetHeight
|
|
52
76
|
const isBottom = Math.abs(scrollY + innerHeight - offsetHeight) < 1
|
|
53
77
|
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
78
|
+
// resolvedHeaders may be repositioned, hidden or fix positioned
|
|
79
|
+
const headers = resolvedHeaders
|
|
80
|
+
.map(({ element, link }) => ({
|
|
81
|
+
link,
|
|
82
|
+
top: getAbsoluteTop(element),
|
|
83
|
+
}))
|
|
84
|
+
.filter(({ top }) => !Number.isNaN(top))
|
|
85
|
+
.sort((a, b) => a.top - b.top)
|
|
86
|
+
|
|
87
|
+
// no headers available for active link
|
|
88
|
+
if (!headers.length) {
|
|
89
|
+
activateLink(null)
|
|
58
90
|
return
|
|
59
91
|
}
|
|
60
92
|
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
for (let i = 0; i < anchors.length; i++) {
|
|
66
|
-
const anchor = anchors[i]
|
|
67
|
-
const nextAnchor = anchors[i + 1]
|
|
68
|
-
|
|
69
|
-
const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor)
|
|
70
|
-
|
|
71
|
-
if (isActive) {
|
|
72
|
-
activateLink(hash)
|
|
73
|
-
return
|
|
74
|
-
}
|
|
93
|
+
// page top
|
|
94
|
+
if (scrollY < 1) {
|
|
95
|
+
activateLink(null)
|
|
96
|
+
return
|
|
75
97
|
}
|
|
76
|
-
}
|
|
77
98
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// container.value.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
99
|
+
// page bottom - highlight last link
|
|
100
|
+
if (isBottom) {
|
|
101
|
+
activateLink(headers[headers.length - 1].link)
|
|
82
102
|
return
|
|
83
103
|
}
|
|
84
104
|
|
|
85
|
-
|
|
86
|
-
|
|
105
|
+
// find the last header above the top of viewport
|
|
106
|
+
let activeLink: string | null = null
|
|
107
|
+
for (const { link, top } of headers) {
|
|
108
|
+
if (top > scrollY + 4 + PAGE_OFFSET)
|
|
109
|
+
break
|
|
87
110
|
|
|
88
|
-
|
|
89
|
-
|
|
111
|
+
activeLink = link
|
|
112
|
+
}
|
|
113
|
+
activateLink(activeLink)
|
|
90
114
|
}
|
|
91
115
|
|
|
92
116
|
function activateLink(hash: string | null) {
|
|
@@ -116,26 +140,3 @@ export function useActiveAnchor(
|
|
|
116
140
|
}
|
|
117
141
|
}
|
|
118
142
|
}
|
|
119
|
-
|
|
120
|
-
function getAnchorTop(anchor: HTMLAnchorElement): number {
|
|
121
|
-
return anchor.parentElement!.offsetTop - PAGE_OFFSET - 15
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function isAnchorActive(
|
|
125
|
-
index: number,
|
|
126
|
-
anchor: HTMLAnchorElement,
|
|
127
|
-
nextAnchor: HTMLAnchorElement | undefined,
|
|
128
|
-
): [boolean, string | null] {
|
|
129
|
-
const scrollTop = window.scrollY
|
|
130
|
-
|
|
131
|
-
if (index === 0 && scrollTop === 0)
|
|
132
|
-
return [true, null]
|
|
133
|
-
|
|
134
|
-
if (scrollTop < getAnchorTop(anchor))
|
|
135
|
-
return [false, null]
|
|
136
|
-
|
|
137
|
-
if (!nextAnchor || scrollTop < getAnchorTop(nextAnchor))
|
|
138
|
-
return [true, anchor.hash]
|
|
139
|
-
|
|
140
|
-
return [false, null]
|
|
141
|
-
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { computed } from 'vue'
|
|
2
|
+
import { useRoute } from 'vue-router'
|
|
3
|
+
|
|
4
|
+
export function usePagination(options: {
|
|
5
|
+
/**
|
|
6
|
+
* Post 总数
|
|
7
|
+
*/
|
|
8
|
+
total: number
|
|
9
|
+
/**
|
|
10
|
+
* 每页数量
|
|
11
|
+
*/
|
|
12
|
+
pageSize: number
|
|
13
|
+
}) {
|
|
14
|
+
const route = useRoute()
|
|
15
|
+
const curPage = computed<number>(() => Number.parseInt((route.params as { page: string }).page || '1'))
|
|
16
|
+
|
|
17
|
+
const totalPages = computed(() => Math.ceil(options.total / options.pageSize))
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 围绕的长度
|
|
21
|
+
*/
|
|
22
|
+
const surLen = computed(() => {
|
|
23
|
+
if (curPage.value === 1 || curPage.value === totalPages.value)
|
|
24
|
+
return 3
|
|
25
|
+
else
|
|
26
|
+
return 2
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
function showPage(i: number) {
|
|
30
|
+
if (i === 1)
|
|
31
|
+
return true
|
|
32
|
+
else if (i === totalPages.value)
|
|
33
|
+
return true
|
|
34
|
+
return i > curPage.value - surLen.value && i < curPage.value + surLen.value
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getTo(i: number) {
|
|
38
|
+
if (i === 1)
|
|
39
|
+
return '/'
|
|
40
|
+
else return `/page/${i}`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const prevTo = computed(() => {
|
|
44
|
+
return getTo(curPage.value - 1)
|
|
45
|
+
})
|
|
46
|
+
const nextTo = computed(() => {
|
|
47
|
+
return getTo(curPage.value + 1)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const showPrev = computed(() => curPage.value > 1)
|
|
51
|
+
const showNext = computed(() => curPage.value < totalPages.value)
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
curPage,
|
|
55
|
+
totalPages,
|
|
56
|
+
showPage,
|
|
57
|
+
surLen,
|
|
58
|
+
|
|
59
|
+
getTo,
|
|
60
|
+
prevTo,
|
|
61
|
+
nextTo,
|
|
62
|
+
showPrev,
|
|
63
|
+
showNext,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { computed, ref
|
|
1
|
+
import { computed, ref } from 'vue'
|
|
2
2
|
import { useFrontmatter } from './common'
|
|
3
|
-
import { useLayout
|
|
3
|
+
import { useLayout } from './layout'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* helper for sidebar
|
|
7
|
+
* @inner
|
|
7
8
|
*/
|
|
8
9
|
export function useSidebar() {
|
|
9
10
|
const isOpen = ref(false)
|
|
@@ -37,41 +38,3 @@ export function useSidebar() {
|
|
|
37
38
|
toggle,
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* dynamic left sidebar logic
|
|
43
|
-
* - sidebar is hidden by default when home or mobile
|
|
44
|
-
* - sidebar is shown by default when not home and not mobile
|
|
45
|
-
* - sidebar can be toggled by user
|
|
46
|
-
*/
|
|
47
|
-
export function useDynamicLeftSidebar() {
|
|
48
|
-
const layout = useLayout()
|
|
49
|
-
const isMobile = useMobile()
|
|
50
|
-
const isOpen = ref(isMobile.value ? false : layout.value !== 'home')
|
|
51
|
-
|
|
52
|
-
watchEffect(() => {
|
|
53
|
-
if (isMobile.value)
|
|
54
|
-
close()
|
|
55
|
-
else if (layout.value !== 'home')
|
|
56
|
-
open()
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
function open() {
|
|
60
|
-
isOpen.value = true
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function close() {
|
|
64
|
-
isOpen.value = false
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function toggle() {
|
|
68
|
-
isOpen.value ? close() : open()
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
isOpen,
|
|
73
|
-
open,
|
|
74
|
-
close,
|
|
75
|
-
toggle,
|
|
76
|
-
}
|
|
77
|
-
}
|
|
@@ -6,5 +6,13 @@ import type { DefaultTheme, ValaxyConfig } from 'valaxy/types'
|
|
|
6
6
|
import type { ComputedRef } from 'vue'
|
|
7
7
|
|
|
8
8
|
export async function install({ app }: ViteSSGContext, config: ComputedRef<ValaxyConfig<DefaultTheme.Config>>) {
|
|
9
|
-
app.use(FloatingVue,
|
|
9
|
+
app.use(FloatingVue, Object.assign({
|
|
10
|
+
themes: {
|
|
11
|
+
tooltip: {
|
|
12
|
+
delay: {
|
|
13
|
+
show: 0,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
}, config.value.siteConfig.floatingVue || {}))
|
|
10
18
|
}
|
package/client/stores/app.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { acceptHMRUpdate, defineStore } from 'pinia'
|
|
2
|
-
import { useToggle } from '@vueuse/core'
|
|
3
2
|
import { ref } from 'vue'
|
|
4
3
|
import { useMobile, useThemeConfig, useValaxyDark } from 'valaxy'
|
|
5
4
|
|
|
@@ -18,9 +17,6 @@ export const useAppStore = defineStore('app', () => {
|
|
|
18
17
|
const isMobile = useMobile()
|
|
19
18
|
const showLoading = ref(true)
|
|
20
19
|
|
|
21
|
-
// right sidebar with toc
|
|
22
|
-
const [isRightSidebarOpen, toggleRightSidebar] = useToggle(false)
|
|
23
|
-
|
|
24
20
|
return {
|
|
25
21
|
isMobile,
|
|
26
22
|
// for dark
|
|
@@ -30,9 +26,6 @@ export const useAppStore = defineStore('app', () => {
|
|
|
30
26
|
toggleDarkWithTransition,
|
|
31
27
|
|
|
32
28
|
showLoading,
|
|
33
|
-
|
|
34
|
-
isRightSidebarOpen,
|
|
35
|
-
toggleRightSidebar,
|
|
36
29
|
}
|
|
37
30
|
})
|
|
38
31
|
|
|
@@ -25,7 +25,7 @@ html:not(.dark) .vp-code-dark {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
@media (width <=
|
|
28
|
+
@media (width <= 639.9px) {
|
|
29
29
|
.markdown-body li div[class*="language-"] {
|
|
30
30
|
border-radius: 6px 0 0 6px;
|
|
31
31
|
}
|
|
@@ -232,7 +232,7 @@ html:not(.dark) .vp-code-dark {
|
|
|
232
232
|
height: 24px;
|
|
233
233
|
opacity: 1;
|
|
234
234
|
cursor: pointer;
|
|
235
|
-
background-image: linear-gradient(-180deg,
|
|
235
|
+
background-image: linear-gradient(-180deg,rgb(0 0 0 / 0) 0%,var(--va-c-bg-dark) 100%);
|
|
236
236
|
|
|
237
237
|
&::before {
|
|
238
238
|
display: block;
|
|
@@ -5,12 +5,11 @@
|
|
|
5
5
|
.vp-code-group .tabs {
|
|
6
6
|
position: relative;
|
|
7
7
|
display: flex;
|
|
8
|
-
margin-right: -
|
|
9
|
-
margin-left: -
|
|
8
|
+
margin-right: -1rem;
|
|
9
|
+
margin-left: -1rem;
|
|
10
10
|
padding: 0 12px;
|
|
11
11
|
background-color: var(--va-code-tab-bg);
|
|
12
|
-
overflow
|
|
13
|
-
overflow-y: hidden;
|
|
12
|
+
overflow: auto hidden;
|
|
14
13
|
box-shadow: inset 0 -1px var(--va-code-tab-divider);
|
|
15
14
|
}
|
|
16
15
|
|
|
@@ -13,13 +13,13 @@ $palette: map.merge(
|
|
|
13
13
|
"warning": #f2711c,
|
|
14
14
|
|
|
15
15
|
"text-light-1": #213547,
|
|
16
|
-
"text-light-2":
|
|
17
|
-
"text-light-3":
|
|
18
|
-
"text-light-4":
|
|
19
|
-
"text-dark-1":
|
|
20
|
-
"text-dark-2":
|
|
21
|
-
"text-dark-3":
|
|
22
|
-
"text-dark-4":
|
|
16
|
+
"text-light-2": rgb(60 60 60 / 0.7),
|
|
17
|
+
"text-light-3": rgb(60 60 60 / 0.33),
|
|
18
|
+
"text-light-4": rgb(60 60 60 / 0.18),
|
|
19
|
+
"text-dark-1": rgb(255 255 255 / 0.87),
|
|
20
|
+
"text-dark-2": rgb(235 235 235 / 0.6),
|
|
21
|
+
"text-dark-3": rgb(235 235 235 / 0.38),
|
|
22
|
+
"text-dark-4": rgb(235 235 235 / 0.18),
|
|
23
23
|
),
|
|
24
24
|
$palette
|
|
25
25
|
);
|
|
@@ -38,7 +38,7 @@ $colors: map.merge(
|
|
|
38
38
|
(
|
|
39
39
|
"primary-light": color.scale($c-primary, $lightness: 10%),
|
|
40
40
|
"primary-lighter": color.scale($c-primary, $lightness: 20%),
|
|
41
|
-
"primary-dark": color.scale($c-primary, $lightness: -
|
|
41
|
+
"primary-dark": color.scale($c-primary, $lightness: -10%),
|
|
42
42
|
),
|
|
43
43
|
$colors
|
|
44
44
|
);
|
|
@@ -70,7 +70,7 @@ $dark: map.merge(
|
|
|
70
70
|
"c-text-light": #ddd,
|
|
71
71
|
"c-text-lighter": #eee,
|
|
72
72
|
"c-text-dark": rgba(#ebebeb, 0.8),
|
|
73
|
-
"c-link": map.get($colors, "primary-
|
|
73
|
+
"c-link": map.get($colors, "primary-lighter"),
|
|
74
74
|
),
|
|
75
75
|
$dark
|
|
76
76
|
);
|
package/client/utils/helper.ts
CHANGED