vitepress-theme-element-plus 1.3.1 → 1.4.0

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 (45) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +3 -3
  3. package/client/components/A11yTag.vue +29 -29
  4. package/client/components/ApiTyping.vue +54 -54
  5. package/client/components/Backdrop.vue +41 -41
  6. package/client/components/Bili.vue +94 -94
  7. package/client/components/Content.vue +148 -148
  8. package/client/components/DeprecatedTag.vue +19 -19
  9. package/client/components/Doc.vue +219 -185
  10. package/client/components/DocAside.vue +46 -46
  11. package/client/components/DocAsideOutline.vue +145 -145
  12. package/client/components/DocFooter.vue +162 -162
  13. package/client/components/Footer.vue +100 -100
  14. package/client/components/FooterCopyright.vue +27 -27
  15. package/client/components/Layout.vue +159 -156
  16. package/client/components/Link.vue +41 -41
  17. package/client/components/LocalNav.vue +160 -160
  18. package/client/components/MobilePreviewFrame.vue +175 -0
  19. package/client/components/MobilePreviewLayout.vue +140 -0
  20. package/client/components/Nav.vue +69 -69
  21. package/client/components/NavBar.vue +203 -203
  22. package/client/components/NavBarTitle.vue +89 -89
  23. package/client/components/Sidebar.vue +129 -129
  24. package/client/components/SidebarGroup.vue +51 -51
  25. package/client/components/SidebarItem.vue +304 -304
  26. package/client/components/ThemeToggler.vue +129 -129
  27. package/client/components/VPNavBarSearch.vue +23 -23
  28. package/client/hooks/useBackTop.ts +71 -71
  29. package/client/hooks/useLangs.ts +50 -50
  30. package/client/hooks/useSidebarControl.ts +78 -78
  31. package/client/hooks/useSize.ts +69 -69
  32. package/client/icons/dark.vue +8 -8
  33. package/client/icons/light.vue +8 -8
  34. package/client/mobile-preview.ts +60 -0
  35. package/client/utils/client/common.ts +49 -49
  36. package/client/utils/client/outline.ts +116 -116
  37. package/client/utils/common.ts +90 -90
  38. package/index.ts +57 -45
  39. package/package.json +2 -2
  40. package/shared/constants.ts +3 -3
  41. package/styles/base.scss +105 -105
  42. package/styles/code.scss +290 -290
  43. package/styles/doc-content.scss +363 -363
  44. package/styles/index.scss +71 -71
  45. package/styles/tag-content.scss +30 -30
@@ -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
+ }
@@ -1,69 +1,69 @@
1
- import type { MaybeRef } from '@vueuse/core'
2
- import type { Ref, ShallowRef } from 'vue'
3
- import { useEventListener } from '@vueuse/core'
4
- import { computed, isRef, onMounted, ref, shallowRef, unref, watch } from 'vue'
5
- import { isString } from '../utils/common'
6
-
7
- function getValue(value: string | number): string {
8
- return isString(value) ? value : `${value}px`
9
- }
10
-
11
- export interface SizeOptions {
12
- width: string | number | undefined
13
- height: string | number | undefined
14
- ratio: string | number | undefined
15
- }
16
-
17
- export interface SizeInfo<E extends HTMLElement> {
18
- el: ShallowRef<E | undefined>
19
- width: Ref<string>
20
- height: Ref<string>
21
- resize: () => void
22
- }
23
-
24
- export function useSize<E extends HTMLElement>(options: SizeOptions, extraHeight: MaybeRef<number> = 0): SizeInfo<E> {
25
- const el = shallowRef<E>()
26
- const width = computed(() => getValue(unref(options.width) ?? '100%'))
27
- const height = ref('auto')
28
-
29
- const getRadio = (ratio: number | string | undefined): number => {
30
- if (isString(ratio)) {
31
- const [width, height] = ratio.split(':')
32
- const parsedRadio = Number(width) / Number(height)
33
-
34
- if (!Number.isNaN(parsedRadio))
35
- return parsedRadio
36
- }
37
-
38
- return typeof ratio === 'number' ? ratio : 16 / 9
39
- }
40
-
41
- const getHeight = (width: number): string => {
42
- const height = unref(options.height)
43
- const ratio = getRadio(unref(options.ratio))
44
-
45
- return height
46
- ? getValue(height)
47
- : `${Number(width) / ratio + unref(extraHeight)}px`
48
- }
49
-
50
- const updateHeight = (): void => {
51
- if (el.value)
52
- height.value = getHeight(el.value.clientWidth)
53
- }
54
-
55
- onMounted(() => {
56
- updateHeight()
57
- if (isRef(extraHeight))
58
- watch(extraHeight, updateHeight)
59
- useEventListener('orientationchange', updateHeight)
60
- useEventListener('resize', updateHeight)
61
- })
62
-
63
- return {
64
- el,
65
- width,
66
- height,
67
- resize: updateHeight,
68
- }
69
- }
1
+ import type { MaybeRef } from '@vueuse/core'
2
+ import type { Ref, ShallowRef } from 'vue'
3
+ import { useEventListener } from '@vueuse/core'
4
+ import { computed, isRef, onMounted, ref, shallowRef, unref, watch } from 'vue'
5
+ import { isString } from '../utils/common'
6
+
7
+ function getValue(value: string | number): string {
8
+ return isString(value) ? value : `${value}px`
9
+ }
10
+
11
+ export interface SizeOptions {
12
+ width: string | number | undefined
13
+ height: string | number | undefined
14
+ ratio: string | number | undefined
15
+ }
16
+
17
+ export interface SizeInfo<E extends HTMLElement> {
18
+ el: ShallowRef<E | undefined>
19
+ width: Ref<string>
20
+ height: Ref<string>
21
+ resize: () => void
22
+ }
23
+
24
+ export function useSize<E extends HTMLElement>(options: SizeOptions, extraHeight: MaybeRef<number> = 0): SizeInfo<E> {
25
+ const el = shallowRef<E>()
26
+ const width = computed(() => getValue(unref(options.width) ?? '100%'))
27
+ const height = ref('auto')
28
+
29
+ const getRadio = (ratio: number | string | undefined): number => {
30
+ if (isString(ratio)) {
31
+ const [width, height] = ratio.split(':')
32
+ const parsedRadio = Number(width) / Number(height)
33
+
34
+ if (!Number.isNaN(parsedRadio))
35
+ return parsedRadio
36
+ }
37
+
38
+ return typeof ratio === 'number' ? ratio : 16 / 9
39
+ }
40
+
41
+ const getHeight = (width: number): string => {
42
+ const height = unref(options.height)
43
+ const ratio = getRadio(unref(options.ratio))
44
+
45
+ return height
46
+ ? getValue(height)
47
+ : `${Number(width) / ratio + unref(extraHeight)}px`
48
+ }
49
+
50
+ const updateHeight = (): void => {
51
+ if (el.value)
52
+ height.value = getHeight(el.value.clientWidth)
53
+ }
54
+
55
+ onMounted(() => {
56
+ updateHeight()
57
+ if (isRef(extraHeight))
58
+ watch(extraHeight, updateHeight)
59
+ useEventListener('orientationchange', updateHeight)
60
+ useEventListener('resize', updateHeight)
61
+ })
62
+
63
+ return {
64
+ el,
65
+ width,
66
+ height,
67
+ resize: updateHeight,
68
+ }
69
+ }
@@ -1,8 +1,8 @@
1
- <template>
2
- <svg viewBox="0 0 24 24" class="dark-icon">
3
- <path
4
- d="M11.01 3.05C6.51 3.54 3 7.36 3 12a9 9 0 0 0 9 9c4.63 0 8.45-3.5 8.95-8c.09-.79-.78-1.42-1.54-.95A5.403 5.403 0 0 1 11.1 7.5c0-1.06.31-2.06.84-2.89c.45-.67-.04-1.63-.93-1.56z"
5
- fill="currentColor"
6
- />
7
- </svg>
8
- </template>
1
+ <template>
2
+ <svg viewBox="0 0 24 24" class="dark-icon">
3
+ <path
4
+ d="M11.01 3.05C6.51 3.54 3 7.36 3 12a9 9 0 0 0 9 9c4.63 0 8.45-3.5 8.95-8c.09-.79-.78-1.42-1.54-.95A5.403 5.403 0 0 1 11.1 7.5c0-1.06.31-2.06.84-2.89c.45-.67-.04-1.63-.93-1.56z"
5
+ fill="currentColor"
6
+ />
7
+ </svg>
8
+ </template>
@@ -1,8 +1,8 @@
1
- <template>
2
- <svg viewBox="0 0 24 24" class="light-icon">
3
- <path
4
- d="M6.05 4.14l-.39-.39a.993.993 0 0 0-1.4 0l-.01.01a.984.984 0 0 0 0 1.4l.39.39c.39.39 1.01.39 1.4 0l.01-.01a.984.984 0 0 0 0-1.4zM3.01 10.5H1.99c-.55 0-.99.44-.99.99v.01c0 .55.44.99.99.99H3c.56.01 1-.43 1-.98v-.01c0-.56-.44-1-.99-1zm9-9.95H12c-.56 0-1 .44-1 .99v.96c0 .55.44.99.99.99H12c.56.01 1-.43 1-.98v-.97c0-.55-.44-.99-.99-.99zm7.74 3.21c-.39-.39-1.02-.39-1.41-.01l-.39.39a.984.984 0 0 0 0 1.4l.01.01c.39.39 1.02.39 1.4 0l.39-.39a.984.984 0 0 0 0-1.4zm-1.81 15.1l.39.39a.996.996 0 1 0 1.41-1.41l-.39-.39a.993.993 0 0 0-1.4 0c-.4.4-.4 1.02-.01 1.41zM20 11.49v.01c0 .55.44.99.99.99H22c.55 0 .99-.44.99-.99v-.01c0-.55-.44-.99-.99-.99h-1.01c-.55 0-.99.44-.99.99zM12 5.5c-3.31 0-6 2.69-6 6s2.69 6 6 6s6-2.69 6-6s-2.69-6-6-6zm-.01 16.95H12c.55 0 .99-.44.99-.99v-.96c0-.55-.44-.99-.99-.99h-.01c-.55 0-.99.44-.99.99v.96c0 .55.44.99.99.99zm-7.74-3.21c.39.39 1.02.39 1.41 0l.39-.39a.993.993 0 0 0 0-1.4l-.01-.01a.996.996 0 0 0-1.41 0l-.39.39c-.38.4-.38 1.02.01 1.41z"
5
- fill="currentColor"
6
- />
7
- </svg>
8
- </template>
1
+ <template>
2
+ <svg viewBox="0 0 24 24" class="light-icon">
3
+ <path
4
+ d="M6.05 4.14l-.39-.39a.993.993 0 0 0-1.4 0l-.01.01a.984.984 0 0 0 0 1.4l.39.39c.39.39 1.01.39 1.4 0l.01-.01a.984.984 0 0 0 0-1.4zM3.01 10.5H1.99c-.55 0-.99.44-.99.99v.01c0 .55.44.99.99.99H3c.56.01 1-.43 1-.98v-.01c0-.56-.44-1-.99-1zm9-9.95H12c-.56 0-1 .44-1 .99v.96c0 .55.44.99.99.99H12c.56.01 1-.43 1-.98v-.97c0-.55-.44-.99-.99-.99zm7.74 3.21c-.39-.39-1.02-.39-1.41-.01l-.39.39a.984.984 0 0 0 0 1.4l.01.01c.39.39 1.02.39 1.4 0l.39-.39a.984.984 0 0 0 0-1.4zm-1.81 15.1l.39.39a.996.996 0 1 0 1.41-1.41l-.39-.39a.993.993 0 0 0-1.4 0c-.4.4-.4 1.02-.01 1.41zM20 11.49v.01c0 .55.44.99.99.99H22c.55 0 .99-.44.99-.99v-.01c0-.55-.44-.99-.99-.99h-1.01c-.55 0-.99.44-.99.99zM12 5.5c-3.31 0-6 2.69-6 6s2.69 6 6 6s6-2.69 6-6s-2.69-6-6-6zm-.01 16.95H12c.55 0 .99-.44.99-.99v-.96c0-.55-.44-.99-.99-.99h-.01c-.55 0-.99.44-.99.99v.96c0 .55.44.99.99.99zm-7.74-3.21c.39.39 1.02.39 1.41 0l.39-.39a.993.993 0 0 0 0-1.4l-.01-.01a.996.996 0 0 0-1.41 0l-.39.39c-.38.4-.38 1.02.01 1.41z"
5
+ fill="currentColor"
6
+ />
7
+ </svg>
8
+ </template>
@@ -0,0 +1,60 @@
1
+ import type { InjectionKey } from 'vue'
2
+
3
+ export type MobilePreviewModule = () => Promise<unknown>
4
+
5
+ export type MobilePreviewRegistry = Record<string, MobilePreviewModule>
6
+
7
+ export interface EPMobilePreviewConfig {
8
+ /**
9
+ * Locale-relative path of the standalone preview page.
10
+ *
11
+ * @default '/preview/'
12
+ */
13
+ previewPath?: string
14
+ /**
15
+ * Outer device frame width used in the doc layout.
16
+ *
17
+ * @default 390
18
+ */
19
+ deviceWidth?: number
20
+ /**
21
+ * Inner viewport height used in the doc layout.
22
+ *
23
+ * @default 760
24
+ */
25
+ deviceHeight?: number
26
+ /**
27
+ * Root directory used to resolve the `mobileDemo` frontmatter field.
28
+ *
29
+ * @default 'demo/'
30
+ */
31
+ demoRoot?: string
32
+ }
33
+
34
+ export const mobilePreviewRegistryKey: InjectionKey<MobilePreviewRegistry> = Symbol('vitepress-theme-element-plus.mobile-preview-registry')
35
+
36
+ export function normalizeMobilePreviewId(value: string): string {
37
+ return value
38
+ .trim()
39
+ .replace(/\\/g, '/')
40
+ .replace(/^\.?\//, '')
41
+ }
42
+
43
+ export function normalizeMobilePreviewRoot(value: string | undefined): string {
44
+ if (!value?.trim())
45
+ return 'demo/'
46
+
47
+ return normalizeMobilePreviewId(value)
48
+ .replace(/\/?$/, '/')
49
+ }
50
+
51
+ export function resolveMobilePreviewId(value: string | undefined, root: string | undefined): string {
52
+ const normalizedId = normalizeMobilePreviewId(value ?? '')
53
+ if (!normalizedId)
54
+ return ''
55
+
56
+ const normalizedRoot = normalizeMobilePreviewRoot(root)
57
+ return normalizedId.startsWith(normalizedRoot)
58
+ ? normalizedId
59
+ : `${normalizedRoot}${normalizedId}`
60
+ }
@@ -1,49 +1,49 @@
1
- import type { DefaultTheme } from 'vitepress'
2
- import { isActive } from '../common'
3
-
4
- export interface SidebarLink {
5
- text: string
6
- link: string
7
- docFooterText?: string
8
- }
9
- export function getFlatSideBarLinks(sidebar: DefaultTheme.SidebarItem[]): SidebarLink[] {
10
- const links: SidebarLink[] = []
11
-
12
- function recursivelyExtractLinks(items: DefaultTheme.SidebarItem[]) {
13
- for (const item of items) {
14
- if (item.text && item.link) {
15
- links.push({
16
- text: item.text,
17
- link: item.link,
18
- docFooterText: item.docFooterText,
19
- })
20
- }
21
-
22
- if (item.items) {
23
- recursivelyExtractLinks(item.items)
24
- }
25
- }
26
- }
27
-
28
- recursivelyExtractLinks(sidebar)
29
-
30
- return links
31
- }
32
-
33
- /**
34
- * Check if the given sidebar item contains any active link.
35
- */
36
- export function hasActiveLink(
37
- path: string,
38
- items: DefaultTheme.SidebarItem | DefaultTheme.SidebarItem[],
39
- ): boolean {
40
- if (Array.isArray(items)) {
41
- return items.some(item => hasActiveLink(path, item))
42
- }
43
-
44
- return isActive(path, items.link)
45
- ? true
46
- : items.items
47
- ? hasActiveLink(path, items.items)
48
- : false
49
- }
1
+ import type { DefaultTheme } from 'vitepress'
2
+ import { isActive } from '../common'
3
+
4
+ export interface SidebarLink {
5
+ text: string
6
+ link: string
7
+ docFooterText?: string
8
+ }
9
+ export function getFlatSideBarLinks(sidebar: DefaultTheme.SidebarItem[]): SidebarLink[] {
10
+ const links: SidebarLink[] = []
11
+
12
+ function recursivelyExtractLinks(items: DefaultTheme.SidebarItem[]) {
13
+ for (const item of items) {
14
+ if (item.text && item.link) {
15
+ links.push({
16
+ text: item.text,
17
+ link: item.link,
18
+ docFooterText: item.docFooterText,
19
+ })
20
+ }
21
+
22
+ if (item.items) {
23
+ recursivelyExtractLinks(item.items)
24
+ }
25
+ }
26
+ }
27
+
28
+ recursivelyExtractLinks(sidebar)
29
+
30
+ return links
31
+ }
32
+
33
+ /**
34
+ * Check if the given sidebar item contains any active link.
35
+ */
36
+ export function hasActiveLink(
37
+ path: string,
38
+ items: DefaultTheme.SidebarItem | DefaultTheme.SidebarItem[],
39
+ ): boolean {
40
+ if (Array.isArray(items)) {
41
+ return items.some(item => hasActiveLink(path, item))
42
+ }
43
+
44
+ return isActive(path, items.link)
45
+ ? true
46
+ : items.items
47
+ ? hasActiveLink(path, items.items)
48
+ : false
49
+ }