vitepress-theme-element-plus 0.0.3 → 0.0.4

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 (41) 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 -150
  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 +82 -82
  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 +75 -75
  20. package/client/components/Sidebar.vue +129 -129
  21. package/client/components/SidebarGroup.vue +51 -51
  22. package/client/components/SidebarItem.vue +302 -302
  23. package/client/components/Tag.vue +25 -25
  24. package/client/components/VPNavBarSearch.vue +23 -23
  25. package/client/components/VersionTag.vue +18 -18
  26. package/client/hooks/useBackTop.ts +71 -71
  27. package/client/hooks/useLangs.ts +50 -50
  28. package/client/hooks/useSidebar.ts +93 -18
  29. package/client/hooks/useSidebarControl.ts +78 -78
  30. package/client/hooks/useSize.ts +69 -69
  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 +37 -37
  38. package/styles/code.scss +282 -282
  39. package/styles/doc-content.scss +161 -161
  40. package/styles/index.scss +69 -69
  41. package/styles/tag-content.scss +30 -30
@@ -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,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
+ }
@@ -1,113 +1,113 @@
1
- import type { Header } from 'vitepress'
2
- import type { DefaultTheme } from 'vitepress/theme'
3
-
4
- const ignoreRE = /\b(?:VPBadge|header-anchor|footnote-ref|ignore-header)\b/
5
-
6
- // cached list of anchor elements from resolveHeaders
7
- const resolvedHeaders: { element: HTMLHeadElement, link: string }[] = []
8
-
9
- export type MenuItem = Omit<Header, 'slug' | 'children'> & {
10
- element: HTMLHeadElement
11
- children?: MenuItem[]
12
- }
13
-
14
- export function resolveTitle(theme: DefaultTheme.Config): string {
15
- return (
16
- (typeof theme.outline === 'object'
17
- && !Array.isArray(theme.outline)
18
- && theme.outline.label)
19
- || theme.outlineTitle
20
- || 'On this page'
21
- )
22
- }
23
-
24
- export function getHeaders(range: DefaultTheme.Config['outline']): MenuItem[] {
25
- const headers = Array.from(document.querySelectorAll('.VPDoc :where(h1,h2,h3,h4,h5,h6)'))
26
- .filter(el => el.id && el.hasChildNodes())
27
- .map((el) => {
28
- const level = Number(el.tagName[1])
29
- return {
30
- element: el as HTMLHeadElement,
31
- title: serializeHeader(el),
32
- link: `#${el.id}`,
33
- level,
34
- }
35
- })
36
-
37
- return resolveHeaders(headers, range)
38
- }
39
-
40
- function serializeHeader(h: Element): string {
41
- let ret = ''
42
- for (const node of Array.from(h.childNodes)) {
43
- if (node.nodeType === 1) {
44
- if (ignoreRE.test((node as Element).className))
45
- continue
46
- ret += node.textContent
47
- }
48
- else if (node.nodeType === 3) {
49
- ret += node.textContent
50
- }
51
- }
52
- return ret.trim()
53
- }
54
-
55
- export function resolveHeaders(
56
- headers: MenuItem[],
57
- range?: DefaultTheme.Config['outline'],
58
- ): MenuItem[] {
59
- if (range === false) {
60
- return []
61
- }
62
-
63
- const levelsRange
64
- = (typeof range === 'object' && !Array.isArray(range)
65
- ? range.level
66
- : range) || 2
67
-
68
- const [high, low]: [number, number]
69
- = typeof levelsRange === 'number'
70
- ? [levelsRange, levelsRange]
71
- : levelsRange === 'deep'
72
- ? [2, 6]
73
- : levelsRange
74
-
75
- return buildTree(headers, high, low)
76
- }
77
-
78
- function buildTree(data: MenuItem[], min: number, max: number): MenuItem[] {
79
- resolvedHeaders.length = 0
80
-
81
- const result: MenuItem[] = []
82
- const stack: (MenuItem | { level: number, shouldIgnore: true })[] = []
83
-
84
- data.forEach((item) => {
85
- const node = { ...item, children: [] }
86
- let parent = stack[stack.length - 1]
87
-
88
- while (parent && parent.level >= node.level) {
89
- stack.pop()
90
- parent = stack[stack.length - 1]
91
- }
92
-
93
- if (
94
- node.element.classList.contains('ignore-header')
95
- || (parent && 'shouldIgnore' in parent)
96
- ) {
97
- stack.push({ level: node.level, shouldIgnore: true })
98
- return
99
- }
100
-
101
- if (node.level > max || node.level < min)
102
- return
103
- resolvedHeaders.push({ element: node.element, link: node.link })
104
-
105
- if (parent)
106
- (parent as MenuItem).children.push(node)
107
- else result.push(node)
108
-
109
- stack.push(node)
110
- })
111
-
112
- return result
113
- }
1
+ import type { Header } from 'vitepress'
2
+ import type { DefaultTheme } from 'vitepress/theme'
3
+
4
+ const ignoreRE = /\b(?:VPBadge|header-anchor|footnote-ref|ignore-header)\b/
5
+
6
+ // cached list of anchor elements from resolveHeaders
7
+ const resolvedHeaders: { element: HTMLHeadElement, link: string }[] = []
8
+
9
+ export type MenuItem = Omit<Header, 'slug' | 'children'> & {
10
+ element: HTMLHeadElement
11
+ children?: MenuItem[]
12
+ }
13
+
14
+ export function resolveTitle(theme: DefaultTheme.Config): string {
15
+ return (
16
+ (typeof theme.outline === 'object'
17
+ && !Array.isArray(theme.outline)
18
+ && theme.outline.label)
19
+ || theme.outlineTitle
20
+ || 'On this page'
21
+ )
22
+ }
23
+
24
+ export function getHeaders(range: DefaultTheme.Config['outline']): MenuItem[] {
25
+ const headers = Array.from(document.querySelectorAll('.VPDoc :where(h1,h2,h3,h4,h5,h6)'))
26
+ .filter(el => el.id && el.hasChildNodes())
27
+ .map((el) => {
28
+ const level = Number(el.tagName[1])
29
+ return {
30
+ element: el as HTMLHeadElement,
31
+ title: serializeHeader(el),
32
+ link: `#${el.id}`,
33
+ level,
34
+ }
35
+ })
36
+
37
+ return resolveHeaders(headers, range)
38
+ }
39
+
40
+ function serializeHeader(h: Element): string {
41
+ let ret = ''
42
+ for (const node of Array.from(h.childNodes)) {
43
+ if (node.nodeType === 1) {
44
+ if (ignoreRE.test((node as Element).className))
45
+ continue
46
+ ret += node.textContent
47
+ }
48
+ else if (node.nodeType === 3) {
49
+ ret += node.textContent
50
+ }
51
+ }
52
+ return ret.trim()
53
+ }
54
+
55
+ export function resolveHeaders(
56
+ headers: MenuItem[],
57
+ range?: DefaultTheme.Config['outline'],
58
+ ): MenuItem[] {
59
+ if (range === false) {
60
+ return []
61
+ }
62
+
63
+ const levelsRange
64
+ = (typeof range === 'object' && !Array.isArray(range)
65
+ ? range.level
66
+ : range) || 2
67
+
68
+ const [high, low]: [number, number]
69
+ = typeof levelsRange === 'number'
70
+ ? [levelsRange, levelsRange]
71
+ : levelsRange === 'deep'
72
+ ? [2, 6]
73
+ : levelsRange
74
+
75
+ return buildTree(headers, high, low)
76
+ }
77
+
78
+ function buildTree(data: MenuItem[], min: number, max: number): MenuItem[] {
79
+ resolvedHeaders.length = 0
80
+
81
+ const result: MenuItem[] = []
82
+ const stack: (MenuItem | { level: number, shouldIgnore: true })[] = []
83
+
84
+ data.forEach((item) => {
85
+ const node = { ...item, children: [] }
86
+ let parent = stack[stack.length - 1]
87
+
88
+ while (parent && parent.level >= node.level) {
89
+ stack.pop()
90
+ parent = stack[stack.length - 1]
91
+ }
92
+
93
+ if (
94
+ node.element.classList.contains('ignore-header')
95
+ || (parent && 'shouldIgnore' in parent)
96
+ ) {
97
+ stack.push({ level: node.level, shouldIgnore: true })
98
+ return
99
+ }
100
+
101
+ if (node.level > max || node.level < min)
102
+ return
103
+ resolvedHeaders.push({ element: node.element, link: node.link })
104
+
105
+ if (parent)
106
+ (parent as MenuItem).children.push(node)
107
+ else result.push(node)
108
+
109
+ stack.push(node)
110
+ })
111
+
112
+ return result
113
+ }
@@ -1,90 +1,90 @@
1
- const HASH_RE = /#.*$/
2
- const HASH_OR_QUERY_RE = /[?#].*$/
3
- const INDEX_OR_EXT_RE = /(?:(^|\/)index)?\.(?:md|html)$/
4
-
5
- export const inBrowser = typeof document !== 'undefined'
6
-
7
- export function isActive(
8
- currentPath: string,
9
- matchPath?: string,
10
- asRegex: boolean = false,
11
- ): boolean {
12
- if (matchPath === undefined) {
13
- return false
14
- }
15
-
16
- currentPath = normalize(`/${currentPath}`)
17
-
18
- if (asRegex) {
19
- return new RegExp(matchPath).test(currentPath)
20
- }
21
-
22
- if (normalize(matchPath) !== currentPath) {
23
- return false
24
- }
25
-
26
- const hashMatch = matchPath.match(HASH_RE)
27
-
28
- if (hashMatch) {
29
- return (inBrowser ? location.hash : '') === hashMatch[0]
30
- }
31
-
32
- return true
33
- }
34
-
35
- function normalize(path: string): string {
36
- return decodeURI(path)
37
- .replace(HASH_OR_QUERY_RE, '')
38
- .replace(INDEX_OR_EXT_RE, '$1')
39
- }
40
-
41
- export function ensureStartingSlash(path: string): string {
42
- return /^\//.test(path) ? path : `/${path}`
43
- }
44
-
45
- export function isPlainObject(obj: any) {
46
- // 首先排除 null 和非对象类型
47
- if (obj === null || typeof obj !== 'object') {
48
- return false
49
- }
50
-
51
- // 检查对象的构造函数是否是 Object
52
- if (obj.constructor !== Object) {
53
- return false
54
- }
55
-
56
- // 检查对象的原型是否是 Object.prototype
57
- if (Object.getPrototypeOf(obj) !== Object.prototype) {
58
- return false
59
- }
60
-
61
- return true
62
- }
63
-
64
- export function isString(value) {
65
- return typeof value === 'string'
66
- }
67
-
68
- export function capitalizeFirstLetter(string: string) {
69
- if (!string)
70
- return '' // 如果字符串为空,返回空字符串
71
- return string.charAt(0).toUpperCase() + string.slice(1)
72
- }
73
-
74
- export function throttleAndDebounce(fn: () => void, delay: number): () => void {
75
- let timeoutId: NodeJS.Timeout
76
- let called = false
77
-
78
- return () => {
79
- if (timeoutId)
80
- clearTimeout(timeoutId)
81
-
82
- if (!called) {
83
- fn()
84
- ;(called = true) && setTimeout(() => (called = false), delay)
85
- }
86
- else {
87
- timeoutId = setTimeout(fn, delay)
88
- }
89
- }
90
- }
1
+ const HASH_RE = /#.*$/
2
+ const HASH_OR_QUERY_RE = /[?#].*$/
3
+ const INDEX_OR_EXT_RE = /(?:(^|\/)index)?\.(?:md|html)$/
4
+
5
+ export const inBrowser = typeof document !== 'undefined'
6
+
7
+ export function isActive(
8
+ currentPath: string,
9
+ matchPath?: string,
10
+ asRegex: boolean = false,
11
+ ): boolean {
12
+ if (matchPath === undefined) {
13
+ return false
14
+ }
15
+
16
+ currentPath = normalize(`/${currentPath}`)
17
+
18
+ if (asRegex) {
19
+ return new RegExp(matchPath).test(currentPath)
20
+ }
21
+
22
+ if (normalize(matchPath) !== currentPath) {
23
+ return false
24
+ }
25
+
26
+ const hashMatch = matchPath.match(HASH_RE)
27
+
28
+ if (hashMatch) {
29
+ return (inBrowser ? location.hash : '') === hashMatch[0]
30
+ }
31
+
32
+ return true
33
+ }
34
+
35
+ function normalize(path: string): string {
36
+ return decodeURI(path)
37
+ .replace(HASH_OR_QUERY_RE, '')
38
+ .replace(INDEX_OR_EXT_RE, '$1')
39
+ }
40
+
41
+ export function ensureStartingSlash(path: string): string {
42
+ return /^\//.test(path) ? path : `/${path}`
43
+ }
44
+
45
+ export function isPlainObject(obj: any) {
46
+ // 首先排除 null 和非对象类型
47
+ if (obj === null || typeof obj !== 'object') {
48
+ return false
49
+ }
50
+
51
+ // 检查对象的构造函数是否是 Object
52
+ if (obj.constructor !== Object) {
53
+ return false
54
+ }
55
+
56
+ // 检查对象的原型是否是 Object.prototype
57
+ if (Object.getPrototypeOf(obj) !== Object.prototype) {
58
+ return false
59
+ }
60
+
61
+ return true
62
+ }
63
+
64
+ export function isString(value) {
65
+ return typeof value === 'string'
66
+ }
67
+
68
+ export function capitalizeFirstLetter(string: string) {
69
+ if (!string)
70
+ return '' // 如果字符串为空,返回空字符串
71
+ return string.charAt(0).toUpperCase() + string.slice(1)
72
+ }
73
+
74
+ export function throttleAndDebounce(fn: () => void, delay: number): () => void {
75
+ let timeoutId: NodeJS.Timeout
76
+ let called = false
77
+
78
+ return () => {
79
+ if (timeoutId)
80
+ clearTimeout(timeoutId)
81
+
82
+ if (!called) {
83
+ fn()
84
+ ;(called = true) && setTimeout(() => (called = false), delay)
85
+ }
86
+ else {
87
+ timeoutId = setTimeout(fn, delay)
88
+ }
89
+ }
90
+ }