vitepress-theme-element-plus 0.0.7 → 0.0.8

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.
Files changed (43) hide show
  1. package/README.md +3 -3
  2. package/client/components/A11yTag.vue +29 -29
  3. package/client/components/ApiTyping.vue +54 -54
  4. package/client/components/Backdrop.vue +41 -41
  5. package/client/components/Bili.vue +94 -94
  6. package/client/components/Content.vue +148 -148
  7. package/client/components/DeprecatedTag.vue +19 -19
  8. package/client/components/Doc.vue +181 -181
  9. package/client/components/DocAside.vue +46 -46
  10. package/client/components/DocAsideOutline.vue +87 -87
  11. package/client/components/DocFooter.vue +159 -159
  12. package/client/components/Footer.vue +77 -77
  13. package/client/components/FooterCopyright.vue +27 -27
  14. package/client/components/Layout.vue +156 -156
  15. package/client/components/Link.vue +41 -41
  16. package/client/components/LocalNav.vue +160 -160
  17. package/client/components/Nav.vue +69 -69
  18. package/client/components/NavBar.vue +203 -203
  19. package/client/components/NavBarTitle.vue +83 -75
  20. package/client/components/Sidebar.vue +129 -129
  21. package/client/components/SidebarGroup.vue +51 -51
  22. package/client/components/SidebarItem.vue +303 -302
  23. package/client/components/ThemeToggler.vue +108 -0
  24. package/client/components/VPNavBarSearch.vue +23 -23
  25. package/client/hooks/useBackTop.ts +71 -71
  26. package/client/hooks/useLangs.ts +50 -50
  27. package/client/hooks/useSidebarControl.ts +78 -78
  28. package/client/hooks/useSize.ts +69 -69
  29. package/client/icons/dark.vue +8 -0
  30. package/client/icons/light.vue +8 -0
  31. package/client/utils/client/common.ts +49 -49
  32. package/client/utils/client/outline.ts +113 -113
  33. package/client/utils/common.ts +90 -90
  34. package/index.ts +26 -26
  35. package/package.json +73 -73
  36. package/shared/constants.ts +3 -3
  37. package/styles/base.scss +70 -48
  38. package/styles/code.scss +282 -282
  39. package/styles/doc-content.scss +245 -231
  40. package/styles/index.scss +63 -69
  41. package/styles/tag-content.scss +30 -30
  42. package/client/components/Tag.vue +0 -25
  43. package/client/components/VersionTag.vue +0 -18
@@ -0,0 +1,108 @@
1
+ <script setup lang="ts">
2
+ import type { SwitchInstance } from 'element-plus'
3
+ import { useDark, useToggle } from '@vueuse/core'
4
+ import { ElSwitch } from 'element-plus'
5
+ import { useData } from 'vitepress/client'
6
+ import { nextTick, ref } from 'vue'
7
+ import DarkIcon from '../icons/dark.vue'
8
+ import LightIcon from '../icons/light.vue'
9
+
10
+ defineOptions({ inheritAttrs: false })
11
+
12
+ const { site } = useData()
13
+
14
+ const isDark = useDark()
15
+ const toggleDark = useToggle(isDark)
16
+ const switchRef = ref<SwitchInstance>()
17
+
18
+ function beforeChange() {
19
+ return new Promise<boolean>((resolve) => {
20
+ const isAppearanceTransition = document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches
21
+ if (!isAppearanceTransition) {
22
+ resolve(true)
23
+ return
24
+ }
25
+
26
+ const switchElement = switchRef.value?.$el
27
+ const rect = switchElement.getBoundingClientRect()
28
+ const x = rect.left + rect.width / 2
29
+ const y = rect.top + rect.height / 2
30
+
31
+ const endRadius = Math.hypot(
32
+ Math.max(x, innerWidth - x),
33
+ Math.max(y, innerHeight - y),
34
+ )
35
+
36
+ const ratioX = (100 * x) / innerWidth
37
+ const ratioY = (100 * y) / innerHeight
38
+ const referR = Math.hypot(innerWidth, innerHeight) / Math.SQRT2
39
+ const ratioR = (100 * endRadius) / referR
40
+
41
+ const transition = document.startViewTransition(async () => {
42
+ resolve(true)
43
+ await nextTick()
44
+ })
45
+ transition.ready.then(() => {
46
+ const clipPath = [
47
+ `circle(0% at ${ratioX}% ${ratioY}%)`,
48
+ `circle(${ratioR}% at ${ratioX}% ${ratioY}%)`,
49
+ ]
50
+ document.documentElement.animate(
51
+ {
52
+ clipPath: isDark.value ? [...clipPath].reverse() : clipPath,
53
+ },
54
+ {
55
+ duration: 400,
56
+ easing: 'ease-in',
57
+ fill: 'both',
58
+ pseudoElement: isDark.value
59
+ ? '::view-transition-old(root)'
60
+ : '::view-transition-new(root)',
61
+ },
62
+ )
63
+ })
64
+ })
65
+ }
66
+ </script>
67
+
68
+ <template>
69
+ <ClientOnly>
70
+ <ElSwitch
71
+ v-if="
72
+ site.appearance
73
+ && site.appearance !== 'force-dark'
74
+ && site.appearance !== 'force-auto'
75
+ "
76
+ ref="switchRef"
77
+ :model-value="isDark"
78
+ v-bind="$attrs"
79
+ :before-change="beforeChange"
80
+ :active-action-icon="DarkIcon"
81
+ :inactive-action-icon="LightIcon"
82
+ @change="toggleDark"
83
+ />
84
+ </ClientOnly>
85
+ </template>
86
+
87
+ <style lang="scss" scoped>
88
+ :deep(.el-switch__core) {
89
+ --el-switch-on-color: var(--bg-color-mute);
90
+ --el-switch-off-color: var(--bg-color-mute);
91
+ --el-switch-border-color: var(--border-color);
92
+
93
+ .el-switch__action {
94
+ width: 14px;
95
+ height: 14px;
96
+ }
97
+ }
98
+
99
+ :deep(.dark-icon) {
100
+ border-radius: 50%;
101
+ color: #cfd3dc;
102
+ background-color: #141414;
103
+ }
104
+
105
+ :deep(.light-icon) {
106
+ color: #606266;
107
+ }
108
+ </style>
@@ -1,23 +1,23 @@
1
- <script lang="ts" setup>
2
- import VPNavBarSearch from 'vitepress/dist/client/theme-default/components/VPNavBarSearch.vue'
3
- // compatible with vitepress-plugin-pagefind
4
- </script>
5
-
6
- <template>
7
- <VPNavBarSearch />
8
- </template>
9
-
10
- <style>
11
- @media (min-width: 768px) {
12
- .VPNavBarSearch.VPNavBarSearch {
13
- flex-grow: unset;
14
- padding-right: 24px;
15
- }
16
- }
17
-
18
- @media (min-width: 960px) {
19
- .VPNavBarSearch.VPNavBarSearch {
20
- padding-right: 32px;
21
- }
22
- }
23
- </style>
1
+ <script lang="ts" setup>
2
+ import VPNavBarSearch from 'vitepress/dist/client/theme-default/components/VPNavBarSearch.vue'
3
+ // compatible with vitepress-plugin-pagefind
4
+ </script>
5
+
6
+ <template>
7
+ <VPNavBarSearch />
8
+ </template>
9
+
10
+ <style>
11
+ @media (min-width: 768px) {
12
+ .VPNavBarSearch.VPNavBarSearch {
13
+ flex-grow: unset;
14
+ padding-right: 24px;
15
+ }
16
+ }
17
+
18
+ @media (min-width: 960px) {
19
+ .VPNavBarSearch.VPNavBarSearch {
20
+ padding-right: 32px;
21
+ }
22
+ }
23
+ </style>
@@ -1,74 +1,74 @@
1
1
  import { isClient } from '@vueuse/core'
2
2
  import { onBeforeUnmount, onMounted, ref } from 'vue'
3
3
  import { throttle } from '../utils/throttle'
4
-
5
- const threshold = 960
6
-
7
- const cubic = (value: number): number => value ** 3
8
- function easeInOutCubic(value: number): number {
9
- return value < 0.5 ? cubic(value * 2) / 2 : 1 - cubic((1 - value) * 2) / 2
10
- }
11
-
12
- export function useBackTop(offset = 200) {
13
- const shouldShow = ref(false)
14
- const throttleResize = throttle(onResize, 300)
15
- const throttleScroll = throttle(onScroll, 160)
16
-
17
- onMounted(() => {
18
- if (!isClient)
19
- return
20
- onResize()
21
- onScroll()
22
- window.addEventListener('resize', throttleResize)
23
- })
24
-
25
- onBeforeUnmount(() => {
26
- if (!isClient)
27
- return
28
- window.removeEventListener('resize', throttleResize)
29
- window.removeEventListener('scroll', throttleScroll)
30
- })
31
-
32
- const scrollToTop = () => {
33
- const beginTime = Date.now()
34
- const beginValue = document.documentElement.scrollTop
35
- const rAF = window.requestAnimationFrame
36
- const frameFunc = () => {
37
- const progress = (Date.now() - beginTime) / 500
38
- if (progress < 1) {
39
- document.documentElement.scrollTop
40
- = beginValue * (1 - easeInOutCubic(progress))
41
- rAF(frameFunc)
42
- }
43
- else {
44
- document.documentElement.scrollTop = 0
45
- }
46
- }
47
- rAF(frameFunc)
48
- }
49
-
50
- function onResize() {
51
- if (!isClient)
52
- return
53
-
54
- const { clientWidth } = document.body
55
-
56
- if (clientWidth < threshold) {
57
- window.addEventListener('scroll', throttleScroll)
58
- }
59
- else {
60
- window.removeEventListener('scroll', throttleScroll)
61
- }
62
- }
63
-
64
- function onScroll() {
65
- if (!isClient)
66
- return
67
- shouldShow.value = document.documentElement.scrollTop > offset
68
- }
69
-
70
- return {
71
- shouldShow,
72
- scrollToTop,
73
- }
74
- }
4
+
5
+ const threshold = 960
6
+
7
+ const cubic = (value: number): number => value ** 3
8
+ function easeInOutCubic(value: number): number {
9
+ return value < 0.5 ? cubic(value * 2) / 2 : 1 - cubic((1 - value) * 2) / 2
10
+ }
11
+
12
+ export function useBackTop(offset = 200) {
13
+ const shouldShow = ref(false)
14
+ const throttleResize = throttle(onResize, 300)
15
+ const throttleScroll = throttle(onScroll, 160)
16
+
17
+ onMounted(() => {
18
+ if (!isClient)
19
+ return
20
+ onResize()
21
+ onScroll()
22
+ window.addEventListener('resize', throttleResize)
23
+ })
24
+
25
+ onBeforeUnmount(() => {
26
+ if (!isClient)
27
+ return
28
+ window.removeEventListener('resize', throttleResize)
29
+ window.removeEventListener('scroll', throttleScroll)
30
+ })
31
+
32
+ const scrollToTop = () => {
33
+ const beginTime = Date.now()
34
+ const beginValue = document.documentElement.scrollTop
35
+ const rAF = window.requestAnimationFrame
36
+ const frameFunc = () => {
37
+ const progress = (Date.now() - beginTime) / 500
38
+ if (progress < 1) {
39
+ document.documentElement.scrollTop
40
+ = beginValue * (1 - easeInOutCubic(progress))
41
+ rAF(frameFunc)
42
+ }
43
+ else {
44
+ document.documentElement.scrollTop = 0
45
+ }
46
+ }
47
+ rAF(frameFunc)
48
+ }
49
+
50
+ function onResize() {
51
+ if (!isClient)
52
+ return
53
+
54
+ const { clientWidth } = document.body
55
+
56
+ if (clientWidth < threshold) {
57
+ window.addEventListener('scroll', throttleScroll)
58
+ }
59
+ else {
60
+ window.removeEventListener('scroll', throttleScroll)
61
+ }
62
+ }
63
+
64
+ function onScroll() {
65
+ if (!isClient)
66
+ return
67
+ shouldShow.value = document.documentElement.scrollTop > offset
68
+ }
69
+
70
+ return {
71
+ shouldShow,
72
+ scrollToTop,
73
+ }
74
+ }
@@ -1,50 +1,50 @@
1
- import { useData } from 'vitepress'
2
- import { computed } from 'vue'
3
- import { ensureStartingSlash } from '../utils/common'
4
-
5
- export function useLangs({ correspondingLink = false } = {}) {
6
- const { site, localeIndex, page, theme, hash } = useData()
7
- const currentLang = computed(() => ({
8
- label: site.value.locales[localeIndex.value]?.label,
9
- link:
10
- site.value.locales[localeIndex.value]?.link
11
- || (localeIndex.value === 'root' ? '/' : `/${localeIndex.value}/`),
12
- }))
13
-
14
- const localeLinks = computed(() =>
15
- Object.entries(site.value.locales).flatMap(([key, value]) =>
16
- currentLang.value.label === value.label
17
- ? []
18
- : {
19
- text: value.label,
20
- link:
21
- normalizeLink(
22
- value.link || (key === 'root' ? '/' : `/${key}/`),
23
- theme.value.i18nRouting !== false && correspondingLink,
24
- page.value.relativePath.slice(
25
- currentLang.value.link.length - 1,
26
- ),
27
- !site.value.cleanUrls,
28
- ) + hash.value,
29
- },
30
- ),
31
- )
32
-
33
- return { localeLinks, currentLang }
34
- }
35
-
36
- function normalizeLink(
37
- link: string,
38
- addPath: boolean,
39
- path: string,
40
- addExt: boolean,
41
- ) {
42
- return addPath
43
- ? link.replace(/\/$/, '')
44
- + ensureStartingSlash(
45
- path
46
- .replace(/(^|\/)index\.md$/, '$1')
47
- .replace(/\.md$/, addExt ? '.html' : ''),
48
- )
49
- : link
50
- }
1
+ import { useData } from 'vitepress'
2
+ import { computed } from 'vue'
3
+ import { ensureStartingSlash } from '../utils/common'
4
+
5
+ export function useLangs({ correspondingLink = false } = {}) {
6
+ const { site, localeIndex, page, theme, hash } = useData()
7
+ const currentLang = computed(() => ({
8
+ label: site.value.locales[localeIndex.value]?.label,
9
+ link:
10
+ site.value.locales[localeIndex.value]?.link
11
+ || (localeIndex.value === 'root' ? '/' : `/${localeIndex.value}/`),
12
+ }))
13
+
14
+ const localeLinks = computed(() =>
15
+ Object.entries(site.value.locales).flatMap(([key, value]) =>
16
+ currentLang.value.label === value.label
17
+ ? []
18
+ : {
19
+ text: value.label,
20
+ link:
21
+ normalizeLink(
22
+ value.link || (key === 'root' ? '/' : `/${key}/`),
23
+ theme.value.i18nRouting !== false && correspondingLink,
24
+ page.value.relativePath.slice(
25
+ currentLang.value.link.length - 1,
26
+ ),
27
+ !site.value.cleanUrls,
28
+ ) + hash.value,
29
+ },
30
+ ),
31
+ )
32
+
33
+ return { localeLinks, currentLang }
34
+ }
35
+
36
+ function normalizeLink(
37
+ link: string,
38
+ addPath: boolean,
39
+ path: string,
40
+ addExt: boolean,
41
+ ) {
42
+ return addPath
43
+ ? link.replace(/\/$/, '')
44
+ + ensureStartingSlash(
45
+ path
46
+ .replace(/(^|\/)index\.md$/, '$1')
47
+ .replace(/\.md$/, addExt ? '.html' : ''),
48
+ )
49
+ : link
50
+ }
@@ -1,78 +1,78 @@
1
- import type { DefaultTheme } from 'vitepress'
2
- import type { ComputedRef, Ref } from 'vue'
3
- import { useData } from 'vitepress'
4
- import { computed, onMounted, ref, watch, watchEffect, watchPostEffect } from 'vue'
5
- import { hasActiveLink as containsActiveLink } from '../utils/client/common'
6
-
7
- import { isActive } from '../utils/common'
8
-
9
- export interface SidebarControl {
10
- collapsed: Ref<boolean>
11
- collapsible: ComputedRef<boolean>
12
- isLink: ComputedRef<boolean>
13
- isActiveLink: Ref<boolean>
14
- hasActiveLink: ComputedRef<boolean>
15
- hasChildren: ComputedRef<boolean>
16
- toggle: () => void
17
- }
18
-
19
- export function useSidebarControl(
20
- item: ComputedRef<DefaultTheme.SidebarItem>,
21
- ): SidebarControl {
22
- const { page, hash } = useData()
23
- const collapsed = ref(false)
24
-
25
- const collapsible = computed(() => {
26
- return item.value.collapsed !== undefined
27
- })
28
-
29
- const isLink = computed(() => {
30
- return !!item.value.link
31
- })
32
-
33
- const isActiveLink = ref(false)
34
- const updateIsActiveLink = () => {
35
- isActiveLink.value = isActive(page.value.relativePath, item.value.link)
36
- }
37
-
38
- watch([page, item, hash], updateIsActiveLink)
39
- onMounted(updateIsActiveLink)
40
-
41
- const hasActiveLink = computed(() => {
42
- if (isActiveLink.value) {
43
- return true
44
- }
45
-
46
- return item.value.items
47
- ? containsActiveLink(page.value.relativePath, item.value.items)
48
- : false
49
- })
50
-
51
- const hasChildren = computed(() => {
52
- return !!(item.value.items && item.value.items.length)
53
- })
54
-
55
- watchEffect(() => {
56
- collapsed.value = !!(collapsible.value && item.value.collapsed)
57
- })
58
-
59
- watchPostEffect(() => {
60
- ;(isActiveLink.value || hasActiveLink.value) && (collapsed.value = false)
61
- })
62
-
63
- function toggle() {
64
- if (collapsible.value) {
65
- collapsed.value = !collapsed.value
66
- }
67
- }
68
-
69
- return {
70
- collapsed,
71
- collapsible,
72
- isLink,
73
- isActiveLink,
74
- hasActiveLink,
75
- hasChildren,
76
- toggle,
77
- }
78
- }
1
+ import type { DefaultTheme } from 'vitepress'
2
+ import type { ComputedRef, Ref } from 'vue'
3
+ import { useData } from 'vitepress'
4
+ import { computed, onMounted, ref, watch, watchEffect, watchPostEffect } from 'vue'
5
+ import { hasActiveLink as containsActiveLink } from '../utils/client/common'
6
+
7
+ import { isActive } from '../utils/common'
8
+
9
+ export interface SidebarControl {
10
+ collapsed: Ref<boolean>
11
+ collapsible: ComputedRef<boolean>
12
+ isLink: ComputedRef<boolean>
13
+ isActiveLink: Ref<boolean>
14
+ hasActiveLink: ComputedRef<boolean>
15
+ hasChildren: ComputedRef<boolean>
16
+ toggle: () => void
17
+ }
18
+
19
+ export function useSidebarControl(
20
+ item: ComputedRef<DefaultTheme.SidebarItem>,
21
+ ): SidebarControl {
22
+ const { page, hash } = useData()
23
+ const collapsed = ref(false)
24
+
25
+ const collapsible = computed(() => {
26
+ return item.value.collapsed !== undefined
27
+ })
28
+
29
+ const isLink = computed(() => {
30
+ return !!item.value.link
31
+ })
32
+
33
+ const isActiveLink = ref(false)
34
+ const updateIsActiveLink = () => {
35
+ isActiveLink.value = isActive(page.value.relativePath, item.value.link)
36
+ }
37
+
38
+ watch([page, item, hash], updateIsActiveLink)
39
+ onMounted(updateIsActiveLink)
40
+
41
+ const hasActiveLink = computed(() => {
42
+ if (isActiveLink.value) {
43
+ return true
44
+ }
45
+
46
+ return item.value.items
47
+ ? containsActiveLink(page.value.relativePath, item.value.items)
48
+ : false
49
+ })
50
+
51
+ const hasChildren = computed(() => {
52
+ return !!(item.value.items && item.value.items.length)
53
+ })
54
+
55
+ watchEffect(() => {
56
+ collapsed.value = !!(collapsible.value && item.value.collapsed)
57
+ })
58
+
59
+ watchPostEffect(() => {
60
+ ;(isActiveLink.value || hasActiveLink.value) && (collapsed.value = false)
61
+ })
62
+
63
+ function toggle() {
64
+ if (collapsible.value) {
65
+ collapsed.value = !collapsed.value
66
+ }
67
+ }
68
+
69
+ return {
70
+ collapsed,
71
+ collapsible,
72
+ isLink,
73
+ isActiveLink,
74
+ hasActiveLink,
75
+ hasChildren,
76
+ toggle,
77
+ }
78
+ }